Pointers in Masked Load, Store, Gather, Scatter intrinsics
[oota-llvm.git] / test / Transforms / LoopVectorize / X86 / masked_load_store.ll
1 ; RUN: opt < %s  -O3 -mcpu=corei7-avx -S | FileCheck %s -check-prefix=AVX1
2 ; RUN: opt < %s  -O3 -mcpu=core-avx2 -S | FileCheck %s -check-prefix=AVX2
3 ; RUN: opt < %s  -O3 -mcpu=knl -S | FileCheck %s -check-prefix=AVX512
4
5 ;AVX1-NOT: llvm.masked
6
7 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8 target triple = "x86_64-pc_linux"
9
10 ; The source code:
11 ;
12 ;void foo1(int *A, int *B, int *trigger) {
13 ;
14 ;  for (int i=0; i<10000; i++) {
15 ;    if (trigger[i] < 100) {
16 ;          A[i] = B[i] + trigger[i];
17 ;    }
18 ;  }
19 ;}
20
21 ;AVX2-LABEL: @foo1
22 ;AVX2: icmp slt <8 x i32> %wide.load, <i32 100, i32 100, i32 100
23 ;AVX2: call <8 x i32> @llvm.masked.load.v8i32
24 ;AVX2: add nsw <8 x i32>
25 ;AVX2: call void @llvm.masked.store.v8i32
26 ;AVX2: ret void
27
28 ;AVX512-LABEL: @foo1
29 ;AVX512: icmp slt <16 x i32> %wide.load, <i32 100, i32 100, i32 100
30 ;AVX512: call <16 x i32> @llvm.masked.load.v16i32
31 ;AVX512: add nsw <16 x i32>
32 ;AVX512: call void @llvm.masked.store.v16i32
33 ;AVX512: ret void
34
35 ; Function Attrs: nounwind uwtable
36 define void @foo1(i32* %A, i32* %B, i32* %trigger) {
37 entry:
38   %A.addr = alloca i32*, align 8
39   %B.addr = alloca i32*, align 8
40   %trigger.addr = alloca i32*, align 8
41   %i = alloca i32, align 4
42   store i32* %A, i32** %A.addr, align 8
43   store i32* %B, i32** %B.addr, align 8
44   store i32* %trigger, i32** %trigger.addr, align 8
45   store i32 0, i32* %i, align 4
46   br label %for.cond
47
48 for.cond:                                         ; preds = %for.inc, %entry
49   %0 = load i32, i32* %i, align 4
50   %cmp = icmp slt i32 %0, 10000
51   br i1 %cmp, label %for.body, label %for.end
52
53 for.body:                                         ; preds = %for.cond
54   %1 = load i32, i32* %i, align 4
55   %idxprom = sext i32 %1 to i64
56   %2 = load i32*, i32** %trigger.addr, align 8
57   %arrayidx = getelementptr inbounds i32, i32* %2, i64 %idxprom
58   %3 = load i32, i32* %arrayidx, align 4
59   %cmp1 = icmp slt i32 %3, 100
60   br i1 %cmp1, label %if.then, label %if.end
61
62 if.then:                                          ; preds = %for.body
63   %4 = load i32, i32* %i, align 4
64   %idxprom2 = sext i32 %4 to i64
65   %5 = load i32*, i32** %B.addr, align 8
66   %arrayidx3 = getelementptr inbounds i32, i32* %5, i64 %idxprom2
67   %6 = load i32, i32* %arrayidx3, align 4
68   %7 = load i32, i32* %i, align 4
69   %idxprom4 = sext i32 %7 to i64
70   %8 = load i32*, i32** %trigger.addr, align 8
71   %arrayidx5 = getelementptr inbounds i32, i32* %8, i64 %idxprom4
72   %9 = load i32, i32* %arrayidx5, align 4
73   %add = add nsw i32 %6, %9
74   %10 = load i32, i32* %i, align 4
75   %idxprom6 = sext i32 %10 to i64
76   %11 = load i32*, i32** %A.addr, align 8
77   %arrayidx7 = getelementptr inbounds i32, i32* %11, i64 %idxprom6
78   store i32 %add, i32* %arrayidx7, align 4
79   br label %if.end
80
81 if.end:                                           ; preds = %if.then, %for.body
82   br label %for.inc
83
84 for.inc:                                          ; preds = %if.end
85   %12 = load i32, i32* %i, align 4
86   %inc = add nsw i32 %12, 1
87   store i32 %inc, i32* %i, align 4
88   br label %for.cond
89
90 for.end:                                          ; preds = %for.cond
91   ret void
92 }
93
94 ; The source code:
95 ;
96 ;void foo2(float *A, float *B, int *trigger) {
97 ;
98 ;  for (int i=0; i<10000; i++) {
99 ;    if (trigger[i] < 100) {
100 ;          A[i] = B[i] + trigger[i];
101 ;    }
102 ;  }
103 ;}
104
105 ;AVX2-LABEL: @foo2
106 ;AVX2: icmp slt <8 x i32> %wide.load, <i32 100, i32 100, i32 100
107 ;AVX2: call <8 x float> @llvm.masked.load.v8f32
108 ;AVX2: fadd <8 x float>
109 ;AVX2: call void @llvm.masked.store.v8f32
110 ;AVX2: ret void
111
112 ;AVX512-LABEL: @foo2
113 ;AVX512: icmp slt <16 x i32> %wide.load, <i32 100, i32 100, i32 100
114 ;AVX512: call <16 x float> @llvm.masked.load.v16f32
115 ;AVX512: fadd <16 x float>
116 ;AVX512: call void @llvm.masked.store.v16f32
117 ;AVX512: ret void
118
119 ; Function Attrs: nounwind uwtable
120 define void @foo2(float* %A, float* %B, i32* %trigger) {
121 entry:
122   %A.addr = alloca float*, align 8
123   %B.addr = alloca float*, align 8
124   %trigger.addr = alloca i32*, align 8
125   %i = alloca i32, align 4
126   store float* %A, float** %A.addr, align 8
127   store float* %B, float** %B.addr, align 8
128   store i32* %trigger, i32** %trigger.addr, align 8
129   store i32 0, i32* %i, align 4
130   br label %for.cond
131
132 for.cond:                                         ; preds = %for.inc, %entry
133   %0 = load i32, i32* %i, align 4
134   %cmp = icmp slt i32 %0, 10000
135   br i1 %cmp, label %for.body, label %for.end
136
137 for.body:                                         ; preds = %for.cond
138   %1 = load i32, i32* %i, align 4
139   %idxprom = sext i32 %1 to i64
140   %2 = load i32*, i32** %trigger.addr, align 8
141   %arrayidx = getelementptr inbounds i32, i32* %2, i64 %idxprom
142   %3 = load i32, i32* %arrayidx, align 4
143   %cmp1 = icmp slt i32 %3, 100
144   br i1 %cmp1, label %if.then, label %if.end
145
146 if.then:                                          ; preds = %for.body
147   %4 = load i32, i32* %i, align 4
148   %idxprom2 = sext i32 %4 to i64
149   %5 = load float*, float** %B.addr, align 8
150   %arrayidx3 = getelementptr inbounds float, float* %5, i64 %idxprom2
151   %6 = load float, float* %arrayidx3, align 4
152   %7 = load i32, i32* %i, align 4
153   %idxprom4 = sext i32 %7 to i64
154   %8 = load i32*, i32** %trigger.addr, align 8
155   %arrayidx5 = getelementptr inbounds i32, i32* %8, i64 %idxprom4
156   %9 = load i32, i32* %arrayidx5, align 4
157   %conv = sitofp i32 %9 to float
158   %add = fadd float %6, %conv
159   %10 = load i32, i32* %i, align 4
160   %idxprom6 = sext i32 %10 to i64
161   %11 = load float*, float** %A.addr, align 8
162   %arrayidx7 = getelementptr inbounds float, float* %11, i64 %idxprom6
163   store float %add, float* %arrayidx7, align 4
164   br label %if.end
165
166 if.end:                                           ; preds = %if.then, %for.body
167   br label %for.inc
168
169 for.inc:                                          ; preds = %if.end
170   %12 = load i32, i32* %i, align 4
171   %inc = add nsw i32 %12, 1
172   store i32 %inc, i32* %i, align 4
173   br label %for.cond
174
175 for.end:                                          ; preds = %for.cond
176   ret void
177 }
178
179 ; The source code:
180 ;
181 ;void foo3(double *A, double *B, int *trigger) {
182 ;
183 ;  for (int i=0; i<10000; i++) {
184 ;    if (trigger[i] < 100) {
185 ;          A[i] = B[i] + trigger[i];
186 ;    }
187 ;  }
188 ;}
189
190 ;AVX2-LABEL: @foo3
191 ;AVX2: icmp slt <4 x i32> %wide.load, <i32 100, i32 100,
192 ;AVX2: call <4 x double> @llvm.masked.load.v4f64
193 ;AVX2: sitofp <4 x i32> %wide.load to <4 x double>
194 ;AVX2: fadd <4 x double>
195 ;AVX2: call void @llvm.masked.store.v4f64
196 ;AVX2: ret void
197
198 ;AVX512-LABEL: @foo3
199 ;AVX512: icmp slt <8 x i32> %wide.load, <i32 100, i32 100,
200 ;AVX512: call <8 x double> @llvm.masked.load.v8f64
201 ;AVX512: sitofp <8 x i32> %wide.load to <8 x double>
202 ;AVX512: fadd <8 x double>
203 ;AVX512: call void @llvm.masked.store.v8f64
204 ;AVX512: ret void
205
206
207 ; Function Attrs: nounwind uwtable
208 define void @foo3(double* %A, double* %B, i32* %trigger) #0 {
209 entry:
210   %A.addr = alloca double*, align 8
211   %B.addr = alloca double*, align 8
212   %trigger.addr = alloca i32*, align 8
213   %i = alloca i32, align 4
214   store double* %A, double** %A.addr, align 8
215   store double* %B, double** %B.addr, align 8
216   store i32* %trigger, i32** %trigger.addr, align 8
217   store i32 0, i32* %i, align 4
218   br label %for.cond
219
220 for.cond:                                         ; preds = %for.inc, %entry
221   %0 = load i32, i32* %i, align 4
222   %cmp = icmp slt i32 %0, 10000
223   br i1 %cmp, label %for.body, label %for.end
224
225 for.body:                                         ; preds = %for.cond
226   %1 = load i32, i32* %i, align 4
227   %idxprom = sext i32 %1 to i64
228   %2 = load i32*, i32** %trigger.addr, align 8
229   %arrayidx = getelementptr inbounds i32, i32* %2, i64 %idxprom
230   %3 = load i32, i32* %arrayidx, align 4
231   %cmp1 = icmp slt i32 %3, 100
232   br i1 %cmp1, label %if.then, label %if.end
233
234 if.then:                                          ; preds = %for.body
235   %4 = load i32, i32* %i, align 4
236   %idxprom2 = sext i32 %4 to i64
237   %5 = load double*, double** %B.addr, align 8
238   %arrayidx3 = getelementptr inbounds double, double* %5, i64 %idxprom2
239   %6 = load double, double* %arrayidx3, align 8
240   %7 = load i32, i32* %i, align 4
241   %idxprom4 = sext i32 %7 to i64
242   %8 = load i32*, i32** %trigger.addr, align 8
243   %arrayidx5 = getelementptr inbounds i32, i32* %8, i64 %idxprom4
244   %9 = load i32, i32* %arrayidx5, align 4
245   %conv = sitofp i32 %9 to double
246   %add = fadd double %6, %conv
247   %10 = load i32, i32* %i, align 4
248   %idxprom6 = sext i32 %10 to i64
249   %11 = load double*, double** %A.addr, align 8
250   %arrayidx7 = getelementptr inbounds double, double* %11, i64 %idxprom6
251   store double %add, double* %arrayidx7, align 8
252   br label %if.end
253
254 if.end:                                           ; preds = %if.then, %for.body
255   br label %for.inc
256
257 for.inc:                                          ; preds = %if.end
258   %12 = load i32, i32* %i, align 4
259   %inc = add nsw i32 %12, 1
260   store i32 %inc, i32* %i, align 4
261   br label %for.cond
262
263 for.end:                                          ; preds = %for.cond
264   ret void
265 }
266
267 ; The source code:
268 ;
269 ;void foo4(double *A, double *B, int *trigger) {
270 ;
271 ;  for (int i=0; i<10000; i++) {
272 ;    if (trigger[i] < 100) {
273 ;          A[i] = B[i*2] + trigger[i]; << non-cosecutive access
274 ;    }
275 ;  }
276 ;}
277
278 ;AVX2-LABEL: @foo4
279 ;AVX2-NOT: llvm.masked
280 ;AVX2: ret void
281
282 ;AVX512-LABEL: @foo4
283 ;AVX512-NOT: llvm.masked
284 ;AVX512: ret void
285
286 ; Function Attrs: nounwind uwtable
287 define void @foo4(double* %A, double* %B, i32* %trigger)  {
288 entry:
289   %A.addr = alloca double*, align 8
290   %B.addr = alloca double*, align 8
291   %trigger.addr = alloca i32*, align 8
292   %i = alloca i32, align 4
293   store double* %A, double** %A.addr, align 8
294   store double* %B, double** %B.addr, align 8
295   store i32* %trigger, i32** %trigger.addr, align 8
296   store i32 0, i32* %i, align 4
297   br label %for.cond
298
299 for.cond:                                         ; preds = %for.inc, %entry
300   %0 = load i32, i32* %i, align 4
301   %cmp = icmp slt i32 %0, 10000
302   br i1 %cmp, label %for.body, label %for.end
303
304 for.body:                                         ; preds = %for.cond
305   %1 = load i32, i32* %i, align 4
306   %idxprom = sext i32 %1 to i64
307   %2 = load i32*, i32** %trigger.addr, align 8
308   %arrayidx = getelementptr inbounds i32, i32* %2, i64 %idxprom
309   %3 = load i32, i32* %arrayidx, align 4
310   %cmp1 = icmp slt i32 %3, 100
311   br i1 %cmp1, label %if.then, label %if.end
312
313 if.then:                                          ; preds = %for.body
314   %4 = load i32, i32* %i, align 4
315   %mul = mul nsw i32 %4, 2
316   %idxprom2 = sext i32 %mul to i64
317   %5 = load double*, double** %B.addr, align 8
318   %arrayidx3 = getelementptr inbounds double, double* %5, i64 %idxprom2
319   %6 = load double, double* %arrayidx3, align 8
320   %7 = load i32, i32* %i, align 4
321   %idxprom4 = sext i32 %7 to i64
322   %8 = load i32*, i32** %trigger.addr, align 8
323   %arrayidx5 = getelementptr inbounds i32, i32* %8, i64 %idxprom4
324   %9 = load i32, i32* %arrayidx5, align 4
325   %conv = sitofp i32 %9 to double
326   %add = fadd double %6, %conv
327   %10 = load i32, i32* %i, align 4
328   %idxprom6 = sext i32 %10 to i64
329   %11 = load double*, double** %A.addr, align 8
330   %arrayidx7 = getelementptr inbounds double, double* %11, i64 %idxprom6
331   store double %add, double* %arrayidx7, align 8
332   br label %if.end
333
334 if.end:                                           ; preds = %if.then, %for.body
335   br label %for.inc
336
337 for.inc:                                          ; preds = %if.end
338   %12 = load i32, i32* %i, align 4
339   %inc = add nsw i32 %12, 1
340   store i32 %inc, i32* %i, align 4
341   br label %for.cond
342
343 for.end:                                          ; preds = %for.cond
344   ret void
345 }
346
347 @a = common global [1 x i32*] zeroinitializer, align 8
348 @c = common global i32* null, align 8
349
350 ; The loop here should not be vectorized due to trapping
351 ; constant expression
352 ;AVX2-LABEL: @foo5
353 ;AVX2-NOT: llvm.masked
354 ;AVX2: store i32 sdiv
355 ;AVX2: ret void
356
357 ;AVX512-LABEL: @foo5
358 ;AVX512-NOT: llvm.masked
359 ;AVX512: store i32 sdiv
360 ;AVX512: ret void
361
362 ; Function Attrs: nounwind uwtable
363 define void @foo5(i32* %A, i32* %B, i32* %trigger) {
364 entry:
365   %A.addr = alloca i32*, align 8
366   %B.addr = alloca i32*, align 8
367   %trigger.addr = alloca i32*, align 8
368   %i = alloca i32, align 4
369   store i32* %A, i32** %A.addr, align 8
370   store i32* %B, i32** %B.addr, align 8
371   store i32* %trigger, i32** %trigger.addr, align 8
372   store i32 0, i32* %i, align 4
373   br label %for.cond
374
375 for.cond:                                         ; preds = %for.inc, %entry
376   %0 = load i32, i32* %i, align 4
377   %cmp = icmp slt i32 %0, 10000
378   br i1 %cmp, label %for.body, label %for.end
379
380 for.body:                                         ; preds = %for.cond
381   %1 = load i32, i32* %i, align 4
382   %idxprom = sext i32 %1 to i64
383   %2 = load i32*, i32** %trigger.addr, align 8
384   %arrayidx = getelementptr inbounds i32, i32* %2, i64 %idxprom
385   %3 = load i32, i32* %arrayidx, align 4
386   %cmp1 = icmp slt i32 %3, 100
387   br i1 %cmp1, label %if.then, label %if.end
388
389 if.then:                                          ; preds = %for.body
390   %4 = load i32, i32* %i, align 4
391   %idxprom2 = sext i32 %4 to i64
392   %5 = load i32*, i32** %B.addr, align 8
393   %arrayidx3 = getelementptr inbounds i32, i32* %5, i64 %idxprom2
394   %6 = load i32, i32* %arrayidx3, align 4
395   %7 = load i32, i32* %i, align 4
396   %idxprom4 = sext i32 %7 to i64
397   %8 = load i32*, i32** %trigger.addr, align 8
398   %arrayidx5 = getelementptr inbounds i32, i32* %8, i64 %idxprom4
399   %9 = load i32, i32* %arrayidx5, align 4
400   %add = add nsw i32 %6, %9
401   %10 = load i32, i32* %i, align 4
402   %idxprom6 = sext i32 %10 to i64
403   %11 = load i32*, i32** %A.addr, align 8
404   %arrayidx7 = getelementptr inbounds i32, i32* %11, i64 %idxprom6
405   store i32 sdiv (i32 1, i32 zext (i1 icmp eq (i32** getelementptr inbounds ([1 x i32*], [1 x i32*]* @a, i64 0, i64 1), i32** @c) to i32)), i32* %arrayidx7, align 4
406   br label %if.end
407
408 if.end:                                           ; preds = %if.then, %for.body
409   br label %for.inc
410
411 for.inc:                                          ; preds = %if.end
412   %12 = load i32, i32* %i, align 4
413   %inc = add nsw i32 %12, 1
414   store i32 %inc, i32* %i, align 4
415   br label %for.cond
416
417 for.end:                                          ; preds = %for.cond
418   ret void
419 }
420
421 ; Reverse loop
422 ;void foo6(double *in, double *out, unsigned size, int *trigger) {
423 ;
424 ;  for (int i=SIZE-1; i>=0; i--) {
425 ;    if (trigger[i] > 0) {
426 ;      out[i] = in[i] + (double) 0.5;
427 ;    }
428 ;  }
429 ;}
430 ;AVX2-LABEL: @foo6
431 ;AVX2: icmp sgt <4 x i32> %reverse, zeroinitializer
432 ;AVX2: shufflevector <4 x i1>{{.*}}<4 x i32> <i32 3, i32 2, i32 1, i32 0>
433 ;AVX2: call <4 x double> @llvm.masked.load.v4f64
434 ;AVX2: fadd <4 x double>
435 ;AVX2: call void @llvm.masked.store.v4f64
436 ;AVX2: ret void
437
438 ;AVX512-LABEL: @foo6
439 ;AVX512: icmp sgt <8 x i32> %reverse, zeroinitializer
440 ;AVX512: shufflevector <8 x i1>{{.*}}<8 x i32> <i32 7, i32 6, i32 5, i32 4
441 ;AVX512: call <8 x double> @llvm.masked.load.v8f64
442 ;AVX512: fadd <8 x double>
443 ;AVX512: call void @llvm.masked.store.v8f64
444 ;AVX512: ret void
445
446
447 define void @foo6(double* %in, double* %out, i32 %size, i32* %trigger) {
448 entry:
449   %in.addr = alloca double*, align 8
450   %out.addr = alloca double*, align 8
451   %size.addr = alloca i32, align 4
452   %trigger.addr = alloca i32*, align 8
453   %i = alloca i32, align 4
454   store double* %in, double** %in.addr, align 8
455   store double* %out, double** %out.addr, align 8
456   store i32 %size, i32* %size.addr, align 4
457   store i32* %trigger, i32** %trigger.addr, align 8
458   store i32 4095, i32* %i, align 4
459   br label %for.cond
460
461 for.cond:                                         ; preds = %for.inc, %entry
462   %0 = load i32, i32* %i, align 4
463   %cmp = icmp sge i32 %0, 0
464   br i1 %cmp, label %for.body, label %for.end
465
466 for.body:                                         ; preds = %for.cond
467   %1 = load i32, i32* %i, align 4
468   %idxprom = sext i32 %1 to i64
469   %2 = load i32*, i32** %trigger.addr, align 8
470   %arrayidx = getelementptr inbounds i32, i32* %2, i64 %idxprom
471   %3 = load i32, i32* %arrayidx, align 4
472   %cmp1 = icmp sgt i32 %3, 0
473   br i1 %cmp1, label %if.then, label %if.end
474
475 if.then:                                          ; preds = %for.body
476   %4 = load i32, i32* %i, align 4
477   %idxprom2 = sext i32 %4 to i64
478   %5 = load double*, double** %in.addr, align 8
479   %arrayidx3 = getelementptr inbounds double, double* %5, i64 %idxprom2
480   %6 = load double, double* %arrayidx3, align 8
481   %add = fadd double %6, 5.000000e-01
482   %7 = load i32, i32* %i, align 4
483   %idxprom4 = sext i32 %7 to i64
484   %8 = load double*, double** %out.addr, align 8
485   %arrayidx5 = getelementptr inbounds double, double* %8, i64 %idxprom4
486   store double %add, double* %arrayidx5, align 8
487   br label %if.end
488
489 if.end:                                           ; preds = %if.then, %for.body
490   br label %for.inc
491
492 for.inc:                                          ; preds = %if.end
493   %9 = load i32, i32* %i, align 4
494   %dec = add nsw i32 %9, -1
495   store i32 %dec, i32* %i, align 4
496   br label %for.cond
497
498 for.end:                                          ; preds = %for.cond
499   ret void
500 }
501
502 ; void foo7 (double * __restrict__  out, double ** __restrict__  in,
503 ;           bool * __restrict__ trigger, unsigned size) {
504 ;
505 ;  for (unsigned i=0; i<size; i++)
506 ;    if (trigger[i] && (in[i] != 0))
507 ;      out[i] = (double) 0.5;
508 ; }
509
510 ;AVX512-LABEL: @foo7
511 ;AVX512: call <8 x double*> @llvm.masked.load.v8p0f64(<8 x double*>*
512 ;AVX512: call void @llvm.masked.store.v8f64
513 ;AVX512: ret void
514
515 define void @foo7(double* noalias %out, double** noalias %in, i8* noalias %trigger, i32 %size) #0 {
516 entry:
517   %out.addr = alloca double*, align 8
518   %in.addr = alloca double**, align 8
519   %trigger.addr = alloca i8*, align 8
520   %size.addr = alloca i32, align 4
521   %i = alloca i32, align 4
522   store double* %out, double** %out.addr, align 8
523   store double** %in, double*** %in.addr, align 8
524   store i8* %trigger, i8** %trigger.addr, align 8
525   store i32 %size, i32* %size.addr, align 4
526   store i32 0, i32* %i, align 4
527   br label %for.cond
528
529 for.cond:                                         ; preds = %for.inc, %entry
530   %0 = load i32, i32* %i, align 4
531   %1 = load i32, i32* %size.addr, align 4
532   %cmp = icmp ult i32 %0, %1
533   br i1 %cmp, label %for.body, label %for.end
534
535 for.body:                                         ; preds = %for.cond
536   %2 = load i32, i32* %i, align 4
537   %idxprom = zext i32 %2 to i64
538   %3 = load i8*, i8** %trigger.addr, align 8
539   %arrayidx = getelementptr inbounds i8, i8* %3, i64 %idxprom
540   %4 = load i8, i8* %arrayidx, align 1
541   %tobool = trunc i8 %4 to i1
542   br i1 %tobool, label %land.lhs.true, label %if.end
543
544 land.lhs.true:                                    ; preds = %for.body
545   %5 = load i32, i32* %i, align 4
546   %idxprom1 = zext i32 %5 to i64
547   %6 = load double**, double*** %in.addr, align 8
548   %arrayidx2 = getelementptr inbounds double*, double** %6, i64 %idxprom1
549   %7 = load double*, double** %arrayidx2, align 8
550   %cmp3 = icmp ne double* %7, null
551   br i1 %cmp3, label %if.then, label %if.end
552
553 if.then:                                          ; preds = %land.lhs.true
554   %8 = load i32, i32* %i, align 4
555   %idxprom4 = zext i32 %8 to i64
556   %9 = load double*, double** %out.addr, align 8
557   %arrayidx5 = getelementptr inbounds double, double* %9, i64 %idxprom4
558   store double 5.000000e-01, double* %arrayidx5, align 8
559   br label %if.end
560
561 if.end:                                           ; preds = %if.then, %land.lhs.true, %for.body
562   br label %for.inc
563
564 for.inc:                                          ; preds = %if.end
565   %10 = load i32, i32* %i, align 4
566   %inc = add i32 %10, 1
567   store i32 %inc, i32* %i, align 4
568   br label %for.cond
569
570 for.end:                                          ; preds = %for.cond
571   ret void
572 }
573
574 ;typedef int (*fp)();
575 ;void foo8 (double* __restrict__  out, fp* __restrict__ in, bool * __restrict__ trigger, unsigned size) {
576 ;
577 ;  for (unsigned i=0; i<size; i++)
578 ;    if (trigger[i] && (in[i] != 0))
579 ;      out[i] = (double) 0.5;
580 ;}
581
582 ;AVX512-LABEL: @foo8
583 ;AVX512: call <8 x i32 ()*> @llvm.masked.load.v8p0f_i32f(<8 x i32 ()*>* %
584 ;AVX512: call void @llvm.masked.store.v8f64
585 ;AVX512: ret void
586
587 define void @foo8(double* noalias %out, i32 ()** noalias %in, i8* noalias %trigger, i32 %size) #0 {
588 entry:
589   %out.addr = alloca double*, align 8
590   %in.addr = alloca i32 ()**, align 8
591   %trigger.addr = alloca i8*, align 8
592   %size.addr = alloca i32, align 4
593   %i = alloca i32, align 4
594   store double* %out, double** %out.addr, align 8
595   store i32 ()** %in, i32 ()*** %in.addr, align 8
596   store i8* %trigger, i8** %trigger.addr, align 8
597   store i32 %size, i32* %size.addr, align 4
598   store i32 0, i32* %i, align 4
599   br label %for.cond
600
601 for.cond:                                         ; preds = %for.inc, %entry
602   %0 = load i32, i32* %i, align 4
603   %1 = load i32, i32* %size.addr, align 4
604   %cmp = icmp ult i32 %0, %1
605   br i1 %cmp, label %for.body, label %for.end
606
607 for.body:                                         ; preds = %for.cond
608   %2 = load i32, i32* %i, align 4
609   %idxprom = zext i32 %2 to i64
610   %3 = load i8*, i8** %trigger.addr, align 8
611   %arrayidx = getelementptr inbounds i8, i8* %3, i64 %idxprom
612   %4 = load i8, i8* %arrayidx, align 1
613   %tobool = trunc i8 %4 to i1
614   br i1 %tobool, label %land.lhs.true, label %if.end
615
616 land.lhs.true:                                    ; preds = %for.body
617   %5 = load i32, i32* %i, align 4
618   %idxprom1 = zext i32 %5 to i64
619   %6 = load i32 ()**, i32 ()*** %in.addr, align 8
620   %arrayidx2 = getelementptr inbounds i32 ()*, i32 ()** %6, i64 %idxprom1
621   %7 = load i32 ()*, i32 ()** %arrayidx2, align 8
622   %cmp3 = icmp ne i32 ()* %7, null
623   br i1 %cmp3, label %if.then, label %if.end
624
625 if.then:                                          ; preds = %land.lhs.true
626   %8 = load i32, i32* %i, align 4
627   %idxprom4 = zext i32 %8 to i64
628   %9 = load double*, double** %out.addr, align 8
629   %arrayidx5 = getelementptr inbounds double, double* %9, i64 %idxprom4
630   store double 5.000000e-01, double* %arrayidx5, align 8
631   br label %if.end
632
633 if.end:                                           ; preds = %if.then, %land.lhs.true, %for.body
634   br label %for.inc
635
636 for.inc:                                          ; preds = %if.end
637   %10 = load i32, i32* %i, align 4
638   %inc = add i32 %10, 1
639   store i32 %inc, i32* %i, align 4
640   br label %for.cond
641
642 for.end:                                          ; preds = %for.cond
643   ret void
644 }