xref: /llvm-project/llvm/test/Transforms/SLPVectorizer/consecutive-access.ll (revision 15ee17c3ce34623261788d7de3c1bdf5860be34e)
1*15ee17c3SElvina Yakubova; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2*15ee17c3SElvina Yakubova; RUN: %if x86-registered-target %{ opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-apple-macosx10.9.0 | FileCheck %s --check-prefixes=CHECK-X86 %}
3*15ee17c3SElvina Yakubova; RUN: %if aarch64-registered-target %{ opt < %s -passes=slp-vectorizer -S -mtriple=aarch64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-AARCH64 %}
4*15ee17c3SElvina Yakubova
5*15ee17c3SElvina Yakubova@A = common global [2000 x double] zeroinitializer, align 16
6*15ee17c3SElvina Yakubova@B = common global [2000 x double] zeroinitializer, align 16
7*15ee17c3SElvina Yakubova@C = common global [2000 x float] zeroinitializer, align 16
8*15ee17c3SElvina Yakubova@D = common global [2000 x float] zeroinitializer, align 16
9*15ee17c3SElvina Yakubova
10*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
11*15ee17c3SElvina Yakubovadefine void @foo_3double(i32 %u) #0 {
12*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_3double(
13*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
14*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4
15*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4
16*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[U]], 3
17*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i64
18*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]
19*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]
20*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
21*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 8
22*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]
23*15ee17c3SElvina Yakubova; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 8
24*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD24:%.*]] = add nsw i32 [[MUL]], 2
25*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM25:%.*]] = sext i32 [[ADD24]] to i64
26*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX26:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM25]]
27*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP3:%.*]] = load double, ptr [[ARRAYIDX26]], align 8
28*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX30:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM25]]
29*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP4:%.*]] = load double, ptr [[ARRAYIDX30]], align 8
30*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD31:%.*]] = fadd double [[TMP3]], [[TMP4]]
31*15ee17c3SElvina Yakubova; CHECK-NEXT:    store double [[ADD31]], ptr [[ARRAYIDX26]], align 8
32*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
33*15ee17c3SElvina Yakubova;
34*15ee17c3SElvina Yakubovaentry:
35*15ee17c3SElvina Yakubova  %u.addr = alloca i32, align 4
36*15ee17c3SElvina Yakubova  store i32 %u, ptr %u.addr, align 4
37*15ee17c3SElvina Yakubova  %mul = mul nsw i32 %u, 3
38*15ee17c3SElvina Yakubova  %idxprom = sext i32 %mul to i64
39*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom
40*15ee17c3SElvina Yakubova  %0 = load double, ptr %arrayidx, align 8
41*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom
42*15ee17c3SElvina Yakubova  %1 = load double, ptr %arrayidx4, align 8
43*15ee17c3SElvina Yakubova  %add5 = fadd double %0, %1
44*15ee17c3SElvina Yakubova  store double %add5, ptr %arrayidx, align 8
45*15ee17c3SElvina Yakubova  %add11 = add nsw i32 %mul, 1
46*15ee17c3SElvina Yakubova  %idxprom12 = sext i32 %add11 to i64
47*15ee17c3SElvina Yakubova  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom12
48*15ee17c3SElvina Yakubova  %2 = load double, ptr %arrayidx13, align 8
49*15ee17c3SElvina Yakubova  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom12
50*15ee17c3SElvina Yakubova  %3 = load double, ptr %arrayidx17, align 8
51*15ee17c3SElvina Yakubova  %add18 = fadd double %2, %3
52*15ee17c3SElvina Yakubova  store double %add18, ptr %arrayidx13, align 8
53*15ee17c3SElvina Yakubova  %add24 = add nsw i32 %mul, 2
54*15ee17c3SElvina Yakubova  %idxprom25 = sext i32 %add24 to i64
55*15ee17c3SElvina Yakubova  %arrayidx26 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom25
56*15ee17c3SElvina Yakubova  %4 = load double, ptr %arrayidx26, align 8
57*15ee17c3SElvina Yakubova  %arrayidx30 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom25
58*15ee17c3SElvina Yakubova  %5 = load double, ptr %arrayidx30, align 8
59*15ee17c3SElvina Yakubova  %add31 = fadd double %4, %5
60*15ee17c3SElvina Yakubova  store double %add31, ptr %arrayidx26, align 8
61*15ee17c3SElvina Yakubova  ret void
62*15ee17c3SElvina Yakubova}
63*15ee17c3SElvina Yakubova
64*15ee17c3SElvina Yakubova; SCEV should be able to tell that accesses A[C1 + C2*i], A[C1 + C2*i], ...
65*15ee17c3SElvina Yakubova; A[C1 + C2*i] are consecutive, if C2 is a power of 2, and C2 > C1 > 0.
66*15ee17c3SElvina Yakubova; Thus, the following code should be vectorized.
67*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
68*15ee17c3SElvina Yakubovadefine void @foo_2double(i32 %u) #0 {
69*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_2double(
70*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
71*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4
72*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4
73*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[U]], 2
74*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i64
75*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]
76*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]
77*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
78*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 8
79*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]
80*15ee17c3SElvina Yakubova; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 8
81*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
82*15ee17c3SElvina Yakubova;
83*15ee17c3SElvina Yakubovaentry:
84*15ee17c3SElvina Yakubova  %u.addr = alloca i32, align 4
85*15ee17c3SElvina Yakubova  store i32 %u, ptr %u.addr, align 4
86*15ee17c3SElvina Yakubova  %mul = mul nsw i32 %u, 2
87*15ee17c3SElvina Yakubova  %idxprom = sext i32 %mul to i64
88*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom
89*15ee17c3SElvina Yakubova  %0 = load double, ptr %arrayidx, align 8
90*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom
91*15ee17c3SElvina Yakubova  %1 = load double, ptr %arrayidx4, align 8
92*15ee17c3SElvina Yakubova  %add5 = fadd double %0, %1
93*15ee17c3SElvina Yakubova  store double %add5, ptr %arrayidx, align 8
94*15ee17c3SElvina Yakubova  %add11 = add nsw i32 %mul, 1
95*15ee17c3SElvina Yakubova  %idxprom12 = sext i32 %add11 to i64
96*15ee17c3SElvina Yakubova  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom12
97*15ee17c3SElvina Yakubova  %2 = load double, ptr %arrayidx13, align 8
98*15ee17c3SElvina Yakubova  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom12
99*15ee17c3SElvina Yakubova  %3 = load double, ptr %arrayidx17, align 8
100*15ee17c3SElvina Yakubova  %add18 = fadd double %2, %3
101*15ee17c3SElvina Yakubova  store double %add18, ptr %arrayidx13, align 8
102*15ee17c3SElvina Yakubova  ret void
103*15ee17c3SElvina Yakubova}
104*15ee17c3SElvina Yakubova
105*15ee17c3SElvina Yakubova; Similar to the previous test, but with different datatype.
106*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
107*15ee17c3SElvina Yakubovadefine void @foo_4float(i32 %u) #0 {
108*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_4float(
109*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
110*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4
111*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4
112*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[U]], 4
113*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i64
114*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 [[IDXPROM]]
115*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 [[IDXPROM]]
116*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x float>, ptr [[ARRAYIDX]], align 4
117*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x float>, ptr [[ARRAYIDX4]], align 4
118*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x float> [[TMP0]], [[TMP1]]
119*15ee17c3SElvina Yakubova; CHECK-NEXT:    store <4 x float> [[TMP2]], ptr [[ARRAYIDX]], align 4
120*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
121*15ee17c3SElvina Yakubova;
122*15ee17c3SElvina Yakubovaentry:
123*15ee17c3SElvina Yakubova  %u.addr = alloca i32, align 4
124*15ee17c3SElvina Yakubova  store i32 %u, ptr %u.addr, align 4
125*15ee17c3SElvina Yakubova  %mul = mul nsw i32 %u, 4
126*15ee17c3SElvina Yakubova  %idxprom = sext i32 %mul to i64
127*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom
128*15ee17c3SElvina Yakubova  %0 = load float, ptr %arrayidx, align 4
129*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom
130*15ee17c3SElvina Yakubova  %1 = load float, ptr %arrayidx4, align 4
131*15ee17c3SElvina Yakubova  %add5 = fadd float %0, %1
132*15ee17c3SElvina Yakubova  store float %add5, ptr %arrayidx, align 4
133*15ee17c3SElvina Yakubova  %add11 = add nsw i32 %mul, 1
134*15ee17c3SElvina Yakubova  %idxprom12 = sext i32 %add11 to i64
135*15ee17c3SElvina Yakubova  %arrayidx13 = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom12
136*15ee17c3SElvina Yakubova  %2 = load float, ptr %arrayidx13, align 4
137*15ee17c3SElvina Yakubova  %arrayidx17 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom12
138*15ee17c3SElvina Yakubova  %3 = load float, ptr %arrayidx17, align 4
139*15ee17c3SElvina Yakubova  %add18 = fadd float %2, %3
140*15ee17c3SElvina Yakubova  store float %add18, ptr %arrayidx13, align 4
141*15ee17c3SElvina Yakubova  %add24 = add nsw i32 %mul, 2
142*15ee17c3SElvina Yakubova  %idxprom25 = sext i32 %add24 to i64
143*15ee17c3SElvina Yakubova  %arrayidx26 = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom25
144*15ee17c3SElvina Yakubova  %4 = load float, ptr %arrayidx26, align 4
145*15ee17c3SElvina Yakubova  %arrayidx30 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom25
146*15ee17c3SElvina Yakubova  %5 = load float, ptr %arrayidx30, align 4
147*15ee17c3SElvina Yakubova  %add31 = fadd float %4, %5
148*15ee17c3SElvina Yakubova  store float %add31, ptr %arrayidx26, align 4
149*15ee17c3SElvina Yakubova  %add37 = add nsw i32 %mul, 3
150*15ee17c3SElvina Yakubova  %idxprom38 = sext i32 %add37 to i64
151*15ee17c3SElvina Yakubova  %arrayidx39 = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom38
152*15ee17c3SElvina Yakubova  %6 = load float, ptr %arrayidx39, align 4
153*15ee17c3SElvina Yakubova  %arrayidx43 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom38
154*15ee17c3SElvina Yakubova  %7 = load float, ptr %arrayidx43, align 4
155*15ee17c3SElvina Yakubova  %add44 = fadd float %6, %7
156*15ee17c3SElvina Yakubova  store float %add44, ptr %arrayidx39, align 4
157*15ee17c3SElvina Yakubova  ret void
158*15ee17c3SElvina Yakubova}
159*15ee17c3SElvina Yakubova
160*15ee17c3SElvina Yakubova; Similar to the previous tests, but now we are dealing with AddRec SCEV.
161*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
162*15ee17c3SElvina Yakubovadefine i32 @foo_loop(ptr %A, i32 %n) #0 {
163*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_loop(
164*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
165*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8
166*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
167*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[SUM:%.*]] = alloca double, align 8
168*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
169*15ee17c3SElvina Yakubova; CHECK-NEXT:    store ptr [[A:%.*]], ptr [[A_ADDR]], align 8
170*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[N:%.*]], ptr [[N_ADDR]], align 4
171*15ee17c3SElvina Yakubova; CHECK-NEXT:    store double 0.000000e+00, ptr [[SUM]], align 8
172*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
173*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 0, [[N]]
174*15ee17c3SElvina Yakubova; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]
175*15ee17c3SElvina Yakubova; CHECK:       for.body.lr.ph:
176*15ee17c3SElvina Yakubova; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
177*15ee17c3SElvina Yakubova; CHECK:       for.body:
178*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
179*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = phi double [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[ADD7:%.*]], [[FOR_BODY]] ]
180*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP0]], 2
181*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i64
182*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IDXPROM]]
183*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
184*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP3:%.*]] = fmul <2 x double> <double 7.000000e+00, double 7.000000e+00>, [[TMP2]]
185*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[TMP3]], i32 0
186*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x double> [[TMP3]], i32 1
187*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD6:%.*]] = fadd double [[TMP4]], [[TMP5]]
188*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD7]] = fadd double [[TMP1]], [[ADD6]]
189*15ee17c3SElvina Yakubova; CHECK-NEXT:    store double [[ADD7]], ptr [[SUM]], align 8
190*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[INC]] = add nsw i32 [[TMP0]], 1
191*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
192*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N]]
193*15ee17c3SElvina Yakubova; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]
194*15ee17c3SElvina Yakubova; CHECK:       for.cond.for.end_crit_edge:
195*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[SPLIT:%.*]] = phi double [ [[ADD7]], [[FOR_BODY]] ]
196*15ee17c3SElvina Yakubova; CHECK-NEXT:    br label [[FOR_END]]
197*15ee17c3SElvina Yakubova; CHECK:       for.end:
198*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi double [ [[SPLIT]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
199*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[CONV:%.*]] = fptosi double [[DOTLCSSA]] to i32
200*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret i32 [[CONV]]
201*15ee17c3SElvina Yakubova;
202*15ee17c3SElvina Yakubovaentry:
203*15ee17c3SElvina Yakubova  %A.addr = alloca ptr, align 8
204*15ee17c3SElvina Yakubova  %n.addr = alloca i32, align 4
205*15ee17c3SElvina Yakubova  %sum = alloca double, align 8
206*15ee17c3SElvina Yakubova  %i = alloca i32, align 4
207*15ee17c3SElvina Yakubova  store ptr %A, ptr %A.addr, align 8
208*15ee17c3SElvina Yakubova  store i32 %n, ptr %n.addr, align 4
209*15ee17c3SElvina Yakubova  store double 0.000000e+00, ptr %sum, align 8
210*15ee17c3SElvina Yakubova  store i32 0, ptr %i, align 4
211*15ee17c3SElvina Yakubova  %cmp1 = icmp slt i32 0, %n
212*15ee17c3SElvina Yakubova  br i1 %cmp1, label %for.body.lr.ph, label %for.end
213*15ee17c3SElvina Yakubova
214*15ee17c3SElvina Yakubovafor.body.lr.ph:                                   ; preds = %entry
215*15ee17c3SElvina Yakubova  br label %for.body
216*15ee17c3SElvina Yakubova
217*15ee17c3SElvina Yakubovafor.body:                                         ; preds = %for.body.lr.ph, %for.body
218*15ee17c3SElvina Yakubova  %0 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
219*15ee17c3SElvina Yakubova  %1 = phi double [ 0.000000e+00, %for.body.lr.ph ], [ %add7, %for.body ]
220*15ee17c3SElvina Yakubova  %mul = mul nsw i32 %0, 2
221*15ee17c3SElvina Yakubova  %idxprom = sext i32 %mul to i64
222*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds double, ptr %A, i64 %idxprom
223*15ee17c3SElvina Yakubova  %2 = load double, ptr %arrayidx, align 8
224*15ee17c3SElvina Yakubova  %mul1 = fmul double 7.000000e+00, %2
225*15ee17c3SElvina Yakubova  %add = add nsw i32 %mul, 1
226*15ee17c3SElvina Yakubova  %idxprom3 = sext i32 %add to i64
227*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds double, ptr %A, i64 %idxprom3
228*15ee17c3SElvina Yakubova  %3 = load double, ptr %arrayidx4, align 8
229*15ee17c3SElvina Yakubova  %mul5 = fmul double 7.000000e+00, %3
230*15ee17c3SElvina Yakubova  %add6 = fadd double %mul1, %mul5
231*15ee17c3SElvina Yakubova  %add7 = fadd double %1, %add6
232*15ee17c3SElvina Yakubova  store double %add7, ptr %sum, align 8
233*15ee17c3SElvina Yakubova  %inc = add nsw i32 %0, 1
234*15ee17c3SElvina Yakubova  store i32 %inc, ptr %i, align 4
235*15ee17c3SElvina Yakubova  %cmp = icmp slt i32 %inc, %n
236*15ee17c3SElvina Yakubova  br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
237*15ee17c3SElvina Yakubova
238*15ee17c3SElvina Yakubovafor.cond.for.end_crit_edge:                       ; preds = %for.body
239*15ee17c3SElvina Yakubova  %split = phi double [ %add7, %for.body ]
240*15ee17c3SElvina Yakubova  br label %for.end
241*15ee17c3SElvina Yakubova
242*15ee17c3SElvina Yakubovafor.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
243*15ee17c3SElvina Yakubova  %.lcssa = phi double [ %split, %for.cond.for.end_crit_edge ], [ 0.000000e+00, %entry ]
244*15ee17c3SElvina Yakubova  %conv = fptosi double %.lcssa to i32
245*15ee17c3SElvina Yakubova  ret i32 %conv
246*15ee17c3SElvina Yakubova}
247*15ee17c3SElvina Yakubova
248*15ee17c3SElvina Yakubova; Similar to foo_2double but with a non-power-of-2 factor and potential
249*15ee17c3SElvina Yakubova; wrapping (both indices wrap or both don't in the same time)
250*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
251*15ee17c3SElvina Yakubovadefine void @foo_2double_non_power_of_2(i32 %u) #0 {
252*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_2double_non_power_of_2(
253*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
254*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4
255*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4
256*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[U]], 6
257*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD6:%.*]] = add i32 [[MUL]], 6
258*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[ADD6]] to i64
259*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]
260*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]
261*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
262*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 8
263*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]
264*15ee17c3SElvina Yakubova; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 8
265*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
266*15ee17c3SElvina Yakubova;
267*15ee17c3SElvina Yakubovaentry:
268*15ee17c3SElvina Yakubova  %u.addr = alloca i32, align 4
269*15ee17c3SElvina Yakubova  store i32 %u, ptr %u.addr, align 4
270*15ee17c3SElvina Yakubova  %mul = mul i32 %u, 6
271*15ee17c3SElvina Yakubova  %add6 = add i32 %mul, 6
272*15ee17c3SElvina Yakubova  %idxprom = sext i32 %add6 to i64
273*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom
274*15ee17c3SElvina Yakubova  %0 = load double, ptr %arrayidx, align 8
275*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom
276*15ee17c3SElvina Yakubova  %1 = load double, ptr %arrayidx4, align 8
277*15ee17c3SElvina Yakubova  %add5 = fadd double %0, %1
278*15ee17c3SElvina Yakubova  store double %add5, ptr %arrayidx, align 8
279*15ee17c3SElvina Yakubova  %add7 = add i32 %mul, 7
280*15ee17c3SElvina Yakubova  %idxprom12 = sext i32 %add7 to i64
281*15ee17c3SElvina Yakubova  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom12
282*15ee17c3SElvina Yakubova  %2 = load double, ptr %arrayidx13, align 8
283*15ee17c3SElvina Yakubova  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom12
284*15ee17c3SElvina Yakubova  %3 = load double, ptr %arrayidx17, align 8
285*15ee17c3SElvina Yakubova  %add18 = fadd double %2, %3
286*15ee17c3SElvina Yakubova  store double %add18, ptr %arrayidx13, align 8
287*15ee17c3SElvina Yakubova  ret void
288*15ee17c3SElvina Yakubova}
289*15ee17c3SElvina Yakubova
290*15ee17c3SElvina Yakubova; Similar to foo_2double_non_power_of_2 but with zext's instead of sext's
291*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
292*15ee17c3SElvina Yakubovadefine void @foo_2double_non_power_of_2_zext(i32 %u) #0 {
293*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_2double_non_power_of_2_zext(
294*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
295*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4
296*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4
297*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[U]], 6
298*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD6:%.*]] = add i32 [[MUL]], 6
299*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[ADD6]] to i64
300*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]
301*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]
302*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
303*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 8
304*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]
305*15ee17c3SElvina Yakubova; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 8
306*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
307*15ee17c3SElvina Yakubova;
308*15ee17c3SElvina Yakubovaentry:
309*15ee17c3SElvina Yakubova  %u.addr = alloca i32, align 4
310*15ee17c3SElvina Yakubova  store i32 %u, ptr %u.addr, align 4
311*15ee17c3SElvina Yakubova  %mul = mul i32 %u, 6
312*15ee17c3SElvina Yakubova  %add6 = add i32 %mul, 6
313*15ee17c3SElvina Yakubova  %idxprom = zext i32 %add6 to i64
314*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom
315*15ee17c3SElvina Yakubova  %0 = load double, ptr %arrayidx, align 8
316*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom
317*15ee17c3SElvina Yakubova  %1 = load double, ptr %arrayidx4, align 8
318*15ee17c3SElvina Yakubova  %add5 = fadd double %0, %1
319*15ee17c3SElvina Yakubova  store double %add5, ptr %arrayidx, align 8
320*15ee17c3SElvina Yakubova  %add7 = add i32 %mul, 7
321*15ee17c3SElvina Yakubova  %idxprom12 = zext i32 %add7 to i64
322*15ee17c3SElvina Yakubova  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom12
323*15ee17c3SElvina Yakubova  %2 = load double, ptr %arrayidx13, align 8
324*15ee17c3SElvina Yakubova  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom12
325*15ee17c3SElvina Yakubova  %3 = load double, ptr %arrayidx17, align 8
326*15ee17c3SElvina Yakubova  %add18 = fadd double %2, %3
327*15ee17c3SElvina Yakubova  store double %add18, ptr %arrayidx13, align 8
328*15ee17c3SElvina Yakubova  ret void
329*15ee17c3SElvina Yakubova}
330*15ee17c3SElvina Yakubova
331*15ee17c3SElvina Yakubova; Similar to foo_2double_non_power_of_2, but now we are dealing with AddRec SCEV.
332*15ee17c3SElvina Yakubova; Alternatively, this is like foo_loop, but with a non-power-of-2 factor and
333*15ee17c3SElvina Yakubova; potential wrapping (both indices wrap or both don't in the same time)
334*15ee17c3SElvina Yakubova; Function Attrs: nounwind ssp uwtable
335*15ee17c3SElvina Yakubovadefine i32 @foo_loop_non_power_of_2(ptr %A, i32 %n) #0 {
336*15ee17c3SElvina Yakubova; CHECK-LABEL: @foo_loop_non_power_of_2(
337*15ee17c3SElvina Yakubova; CHECK-NEXT:  entry:
338*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8
339*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4
340*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[SUM:%.*]] = alloca double, align 8
341*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4
342*15ee17c3SElvina Yakubova; CHECK-NEXT:    store ptr [[A:%.*]], ptr [[A_ADDR]], align 8
343*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[N:%.*]], ptr [[N_ADDR]], align 4
344*15ee17c3SElvina Yakubova; CHECK-NEXT:    store double 0.000000e+00, ptr [[SUM]], align 8
345*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 0, ptr [[I]], align 4
346*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 0, [[N]]
347*15ee17c3SElvina Yakubova; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]
348*15ee17c3SElvina Yakubova; CHECK:       for.body.lr.ph:
349*15ee17c3SElvina Yakubova; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
350*15ee17c3SElvina Yakubova; CHECK:       for.body:
351*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
352*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP1:%.*]] = phi double [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[ADD7:%.*]], [[FOR_BODY]] ]
353*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0]], 12
354*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD_5:%.*]] = add i32 [[MUL]], 5
355*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[ADD_5]] to i64
356*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IDXPROM]]
357*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
358*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP3:%.*]] = fmul <2 x double> <double 7.000000e+00, double 7.000000e+00>, [[TMP2]]
359*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[TMP3]], i32 0
360*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x double> [[TMP3]], i32 1
361*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD6:%.*]] = fadd double [[TMP4]], [[TMP5]]
362*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ADD7]] = fadd double [[TMP1]], [[ADD6]]
363*15ee17c3SElvina Yakubova; CHECK-NEXT:    store double [[ADD7]], ptr [[SUM]], align 8
364*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[INC]] = add i32 [[TMP0]], 1
365*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4
366*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N]]
367*15ee17c3SElvina Yakubova; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]
368*15ee17c3SElvina Yakubova; CHECK:       for.cond.for.end_crit_edge:
369*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[SPLIT:%.*]] = phi double [ [[ADD7]], [[FOR_BODY]] ]
370*15ee17c3SElvina Yakubova; CHECK-NEXT:    br label [[FOR_END]]
371*15ee17c3SElvina Yakubova; CHECK:       for.end:
372*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi double [ [[SPLIT]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
373*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[CONV:%.*]] = fptosi double [[DOTLCSSA]] to i32
374*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret i32 [[CONV]]
375*15ee17c3SElvina Yakubova;
376*15ee17c3SElvina Yakubovaentry:
377*15ee17c3SElvina Yakubova  %A.addr = alloca ptr, align 8
378*15ee17c3SElvina Yakubova  %n.addr = alloca i32, align 4
379*15ee17c3SElvina Yakubova  %sum = alloca double, align 8
380*15ee17c3SElvina Yakubova  %i = alloca i32, align 4
381*15ee17c3SElvina Yakubova  store ptr %A, ptr %A.addr, align 8
382*15ee17c3SElvina Yakubova  store i32 %n, ptr %n.addr, align 4
383*15ee17c3SElvina Yakubova  store double 0.000000e+00, ptr %sum, align 8
384*15ee17c3SElvina Yakubova  store i32 0, ptr %i, align 4
385*15ee17c3SElvina Yakubova  %cmp1 = icmp slt i32 0, %n
386*15ee17c3SElvina Yakubova  br i1 %cmp1, label %for.body.lr.ph, label %for.end
387*15ee17c3SElvina Yakubova
388*15ee17c3SElvina Yakubovafor.body.lr.ph:                                   ; preds = %entry
389*15ee17c3SElvina Yakubova  br label %for.body
390*15ee17c3SElvina Yakubova
391*15ee17c3SElvina Yakubovafor.body:                                         ; preds = %for.body.lr.ph, %for.body
392*15ee17c3SElvina Yakubova  %0 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]
393*15ee17c3SElvina Yakubova  %1 = phi double [ 0.000000e+00, %for.body.lr.ph ], [ %add7, %for.body ]
394*15ee17c3SElvina Yakubova  %mul = mul i32 %0, 12
395*15ee17c3SElvina Yakubova  %add.5 = add i32 %mul, 5
396*15ee17c3SElvina Yakubova  %idxprom = sext i32 %add.5 to i64
397*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds double, ptr %A, i64 %idxprom
398*15ee17c3SElvina Yakubova  %2 = load double, ptr %arrayidx, align 8
399*15ee17c3SElvina Yakubova  %mul1 = fmul double 7.000000e+00, %2
400*15ee17c3SElvina Yakubova  %add.6 = add i32 %mul, 6
401*15ee17c3SElvina Yakubova  %idxprom3 = sext i32 %add.6 to i64
402*15ee17c3SElvina Yakubova  %arrayidx4 = getelementptr inbounds double, ptr %A, i64 %idxprom3
403*15ee17c3SElvina Yakubova  %3 = load double, ptr %arrayidx4, align 8
404*15ee17c3SElvina Yakubova  %mul5 = fmul double 7.000000e+00, %3
405*15ee17c3SElvina Yakubova  %add6 = fadd double %mul1, %mul5
406*15ee17c3SElvina Yakubova  %add7 = fadd double %1, %add6
407*15ee17c3SElvina Yakubova  store double %add7, ptr %sum, align 8
408*15ee17c3SElvina Yakubova  %inc = add i32 %0, 1
409*15ee17c3SElvina Yakubova  store i32 %inc, ptr %i, align 4
410*15ee17c3SElvina Yakubova  %cmp = icmp slt i32 %inc, %n
411*15ee17c3SElvina Yakubova  br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
412*15ee17c3SElvina Yakubova
413*15ee17c3SElvina Yakubovafor.cond.for.end_crit_edge:                       ; preds = %for.body
414*15ee17c3SElvina Yakubova  %split = phi double [ %add7, %for.body ]
415*15ee17c3SElvina Yakubova  br label %for.end
416*15ee17c3SElvina Yakubova
417*15ee17c3SElvina Yakubovafor.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry
418*15ee17c3SElvina Yakubova  %.lcssa = phi double [ %split, %for.cond.for.end_crit_edge ], [ 0.000000e+00, %entry ]
419*15ee17c3SElvina Yakubova  %conv = fptosi double %.lcssa to i32
420*15ee17c3SElvina Yakubova  ret i32 %conv
421*15ee17c3SElvina Yakubova}
422*15ee17c3SElvina Yakubova
423*15ee17c3SElvina Yakubova; This is generated by `clang -std=c11 -Wpedantic -Wall -O3 main.c -S -o - -emit-llvm`
424*15ee17c3SElvina Yakubova; with !{!"clang version 7.0.0 (trunk 337339) (llvm/trunk 337344)"} and stripping off
425*15ee17c3SElvina Yakubova; the !tbaa metadata nodes to fit the rest of the test file, where `cat main.c` is:
426*15ee17c3SElvina Yakubova;
427*15ee17c3SElvina Yakubova;  double bar(ptr a, unsigned n) {
428*15ee17c3SElvina Yakubova;    double x = 0.0;
429*15ee17c3SElvina Yakubova;    double y = 0.0;
430*15ee17c3SElvina Yakubova;    for (unsigned i = 0; i < n; i += 2) {
431*15ee17c3SElvina Yakubova;      x += a[i];
432*15ee17c3SElvina Yakubova;      y += a[i + 1];
433*15ee17c3SElvina Yakubova;    }
434*15ee17c3SElvina Yakubova;    return x * y;
435*15ee17c3SElvina Yakubova;  }
436*15ee17c3SElvina Yakubova;
437*15ee17c3SElvina Yakubova; The resulting IR is similar to @foo_loop, but with zext's instead of sext's.
438*15ee17c3SElvina Yakubova;
439*15ee17c3SElvina Yakubova; Make sure we are able to vectorize this from now on:
440*15ee17c3SElvina Yakubova;
441*15ee17c3SElvina Yakubovadefine double @bar(ptr nocapture readonly %a, i32 %n) local_unnamed_addr #0 {
442*15ee17c3SElvina Yakubova; CHECK-X86-LABEL: @bar(
443*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:  entry:
444*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[N:%.*]], 0
445*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    br i1 [[CMP15]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
446*15ee17c3SElvina Yakubova; CHECK-X86:       for.cond.cleanup:
447*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[TMP0:%.*]] = phi <2 x double> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[FOR_BODY]] ]
448*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[TMP0]], i32 0
449*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[TMP2:%.*]] = extractelement <2 x double> [[TMP0]], i32 1
450*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[MUL:%.*]] = fmul double [[TMP1]], [[TMP2]]
451*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    ret double [[MUL]]
452*15ee17c3SElvina Yakubova; CHECK-X86:       for.body:
453*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[I_018:%.*]] = phi i32 [ [[ADD5:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]
454*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[TMP3:%.*]] = phi <2 x double> [ [[TMP5]], [[FOR_BODY]] ], [ zeroinitializer, [[ENTRY]] ]
455*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[IDXPROM:%.*]] = zext i32 [[I_018]] to i64
456*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[IDXPROM]]
457*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[TMP4:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8
458*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[TMP5]] = fadd <2 x double> [[TMP3]], [[TMP4]]
459*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[ADD5]] = add i32 [[I_018]], 2
460*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD5]], [[N]]
461*15ee17c3SElvina Yakubova; CHECK-X86-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP]]
462*15ee17c3SElvina Yakubova;
463*15ee17c3SElvina Yakubova
464*15ee17c3SElvina Yakubova; CHECK-AARCH64-LABEL: @bar(
465*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:  entry:
466*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[N:%.*]], 0
467*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    br i1 [[CMP15]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
468*15ee17c3SElvina Yakubova; CHECK-AARCH64:       for.cond.cleanup:
469*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[X_0_LCSSA:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]
470*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[Y_0_LCSSA:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[ADD4:%.*]], [[FOR_BODY]] ]
471*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[MUL:%.*]] = fmul double [[X_0_LCSSA]], [[Y_0_LCSSA]]
472*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    ret double [[MUL]]
473*15ee17c3SElvina Yakubova; CHECK-AARCH64:       for.body:
474*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[I_018:%.*]] = phi i32 [ [[ADD5:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]
475*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[Y_017:%.*]] = phi double [ [[ADD4]], [[FOR_BODY]] ], [ 0.000000e+00, [[ENTRY]] ]
476*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[X_016:%.*]] = phi double [ [[ADD]], [[FOR_BODY]] ], [ 0.000000e+00, [[ENTRY]] ]
477*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[IDXPROM:%.*]] = zext i32 [[I_018]] to i64
478*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[IDXPROM]]
479*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8
480*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[ADD]] = fadd double [[X_016]], [[TMP0]]
481*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[ADD1:%.*]] = or disjoint i32 [[I_018]], 1
482*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[IDXPROM2:%.*]] = zext i32 [[ADD1]] to i64
483*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IDXPROM2]]
484*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[TMP1:%.*]] = load double, ptr [[ARRAYIDX3]], align 8
485*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[ADD4]] = fadd double [[Y_017]], [[TMP1]]
486*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[ADD5]] = add i32 [[I_018]], 2
487*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD5]], [[N]]
488*15ee17c3SElvina Yakubova; CHECK-AARCH64-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP]]
489*15ee17c3SElvina Yakubova;
490*15ee17c3SElvina Yakubova
491*15ee17c3SElvina Yakubovaentry:
492*15ee17c3SElvina Yakubova  %cmp15 = icmp eq i32 %n, 0
493*15ee17c3SElvina Yakubova  br i1 %cmp15, label %for.cond.cleanup, label %for.body
494*15ee17c3SElvina Yakubova
495*15ee17c3SElvina Yakubovafor.cond.cleanup:                                 ; preds = %for.body, %entry
496*15ee17c3SElvina Yakubova  %x.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add, %for.body ]
497*15ee17c3SElvina Yakubova  %y.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add4, %for.body ]
498*15ee17c3SElvina Yakubova  %mul = fmul double %x.0.lcssa, %y.0.lcssa
499*15ee17c3SElvina Yakubova  ret double %mul
500*15ee17c3SElvina Yakubova
501*15ee17c3SElvina Yakubovafor.body:                                         ; preds = %entry, %for.body
502*15ee17c3SElvina Yakubova  %i.018 = phi i32 [ %add5, %for.body ], [ 0, %entry ]
503*15ee17c3SElvina Yakubova  %y.017 = phi double [ %add4, %for.body ], [ 0.000000e+00, %entry ]
504*15ee17c3SElvina Yakubova  %x.016 = phi double [ %add, %for.body ], [ 0.000000e+00, %entry ]
505*15ee17c3SElvina Yakubova  %idxprom = zext i32 %i.018 to i64
506*15ee17c3SElvina Yakubova  %arrayidx = getelementptr inbounds double, ptr %a, i64 %idxprom
507*15ee17c3SElvina Yakubova  %0 = load double, ptr %arrayidx, align 8
508*15ee17c3SElvina Yakubova  %add = fadd double %x.016, %0
509*15ee17c3SElvina Yakubova  %add1 = or disjoint i32 %i.018, 1
510*15ee17c3SElvina Yakubova  %idxprom2 = zext i32 %add1 to i64
511*15ee17c3SElvina Yakubova  %arrayidx3 = getelementptr inbounds double, ptr %a, i64 %idxprom2
512*15ee17c3SElvina Yakubova  %1 = load double, ptr %arrayidx3, align 8
513*15ee17c3SElvina Yakubova  %add4 = fadd double %y.017, %1
514*15ee17c3SElvina Yakubova  %add5 = add i32 %i.018, 2
515*15ee17c3SElvina Yakubova  %cmp = icmp ult i32 %add5, %n
516*15ee17c3SElvina Yakubova  br i1 %cmp, label %for.body, label %for.cond.cleanup
517*15ee17c3SElvina Yakubova}
518*15ee17c3SElvina Yakubova
519*15ee17c3SElvina Yakubova; Globals/constant expressions are not normal constants.
520*15ee17c3SElvina Yakubova; They should not be treated as the usual vectorization candidates.
521*15ee17c3SElvina Yakubova
522*15ee17c3SElvina Yakubova@g1 = external global i32, align 4
523*15ee17c3SElvina Yakubova@g2 = external global i32, align 4
524*15ee17c3SElvina Yakubova
525*15ee17c3SElvina Yakubovadefine void @PR33958(ptr nocapture %p) {
526*15ee17c3SElvina Yakubova; CHECK-LABEL: @PR33958(
527*15ee17c3SElvina Yakubova; CHECK-NEXT:    store ptr @g1, ptr [[P:%.*]], align 8
528*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds ptr, ptr [[P]], i64 1
529*15ee17c3SElvina Yakubova; CHECK-NEXT:    store ptr @g2, ptr [[ARRAYIDX1]], align 8
530*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
531*15ee17c3SElvina Yakubova;
532*15ee17c3SElvina Yakubova  store ptr @g1, ptr %p, align 8
533*15ee17c3SElvina Yakubova  %arrayidx1 = getelementptr inbounds ptr, ptr %p, i64 1
534*15ee17c3SElvina Yakubova  store ptr @g2, ptr %arrayidx1, align 8
535*15ee17c3SElvina Yakubova  ret void
536*15ee17c3SElvina Yakubova}
537*15ee17c3SElvina Yakubova
538*15ee17c3SElvina Yakubovadefine void @store_constant_expression(ptr %p) {
539*15ee17c3SElvina Yakubova; CHECK-LABEL: @store_constant_expression(
540*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i64 ptrtoint (ptr @g1 to i64), ptr [[P:%.*]], align 8
541*15ee17c3SElvina Yakubova; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 1
542*15ee17c3SElvina Yakubova; CHECK-NEXT:    store i64 ptrtoint (ptr @g2 to i64), ptr [[ARRAYIDX1]], align 8
543*15ee17c3SElvina Yakubova; CHECK-NEXT:    ret void
544*15ee17c3SElvina Yakubova;
545*15ee17c3SElvina Yakubova  store i64 ptrtoint (ptr @g1 to i64), ptr %p, align 8
546*15ee17c3SElvina Yakubova  %arrayidx1 = getelementptr inbounds i64, ptr %p, i64 1
547*15ee17c3SElvina Yakubova  store i64 ptrtoint (ptr @g2 to i64), ptr %arrayidx1, align 8
548*15ee17c3SElvina Yakubova  ret void
549*15ee17c3SElvina Yakubova}
550*15ee17c3SElvina Yakubova
551*15ee17c3SElvina Yakubovaattributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "frame-pointer"="all" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
552*15ee17c3SElvina Yakubova
553*15ee17c3SElvina Yakubova!llvm.ident = !{!0}
554*15ee17c3SElvina Yakubova
555*15ee17c3SElvina Yakubova!0 = !{!"clang version 3.5.0 "}
556