Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / X86 / imprecise-through-phis.ll
blobfd826ce454ed8e353ffba1542ed6d57cc43966dd
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=loop-vectorize -mtriple=x86_64-apple-darwin %s | FileCheck %s --check-prefixes=CHECK,SSE
3 ; RUN: opt -S -passes=loop-vectorize -mtriple=x86_64-apple-darwin -mattr=+avx %s | FileCheck %s --check-prefixes=CHECK,AVX
5 ; Two mostly identical functions. The only difference is the presence of
6 ; fast-math flags on the second. The loop is a pretty simple reduction:
8 ; for (int i = 0; i < 32; ++i)
9 ;   if (arr[i] != 42)
10 ;     tot += arr[i];
12 define double @sumIfScalar(ptr nocapture readonly %arr) {
13 ; CHECK-LABEL: @sumIfScalar(
14 ; CHECK-NEXT:  entry:
15 ; CHECK-NEXT:    br label [[LOOP:%.*]]
16 ; CHECK:       loop:
17 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[NEXT_ITER:%.*]] ]
18 ; CHECK-NEXT:    [[TOT:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[TOT_NEXT:%.*]], [[NEXT_ITER]] ]
19 ; CHECK-NEXT:    [[ADDR:%.*]] = getelementptr double, ptr [[ARR:%.*]], i32 [[I]]
20 ; CHECK-NEXT:    [[NEXTVAL:%.*]] = load double, ptr [[ADDR]], align 8
21 ; CHECK-NEXT:    [[TST:%.*]] = fcmp une double [[NEXTVAL]], 4.200000e+01
22 ; CHECK-NEXT:    br i1 [[TST]], label [[DO_ADD:%.*]], label [[NO_ADD:%.*]]
23 ; CHECK:       do.add:
24 ; CHECK-NEXT:    [[TOT_NEW:%.*]] = fadd double [[TOT]], [[NEXTVAL]]
25 ; CHECK-NEXT:    br label [[NEXT_ITER]]
26 ; CHECK:       no.add:
27 ; CHECK-NEXT:    br label [[NEXT_ITER]]
28 ; CHECK:       next.iter:
29 ; CHECK-NEXT:    [[TOT_NEXT]] = phi double [ [[TOT]], [[NO_ADD]] ], [ [[TOT_NEW]], [[DO_ADD]] ]
30 ; CHECK-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
31 ; CHECK-NEXT:    [[AGAIN:%.*]] = icmp ult i32 [[I_NEXT]], 32
32 ; CHECK-NEXT:    br i1 [[AGAIN]], label [[LOOP]], label [[DONE:%.*]]
33 ; CHECK:       done:
34 ; CHECK-NEXT:    [[TOT_NEXT_LCSSA:%.*]] = phi double [ [[TOT_NEXT]], [[NEXT_ITER]] ]
35 ; CHECK-NEXT:    ret double [[TOT_NEXT_LCSSA]]
37 entry:
38   br label %loop
40 loop:
41   %i = phi i32 [0, %entry], [%i.next, %next.iter]
42   %tot = phi double [0.0, %entry], [%tot.next, %next.iter]
44   %addr = getelementptr double, ptr %arr, i32 %i
45   %nextval = load double, ptr %addr
47   %tst = fcmp une double %nextval, 42.0
48   br i1 %tst, label %do.add, label %no.add
50 do.add:
51   %tot.new = fadd double %tot, %nextval
52   br label %next.iter
54 no.add:
55   br label %next.iter
57 next.iter:
58   %tot.next = phi double [%tot, %no.add], [%tot.new, %do.add]
59   %i.next = add i32 %i, 1
60   %again = icmp ult i32 %i.next, 32
61   br i1 %again, label %loop, label %done
63 done:
64   ret double %tot.next
67 define double @sumIfVector(ptr nocapture readonly %arr) {
68 ; SSE-LABEL: @sumIfVector(
69 ; SSE-NEXT:  entry:
70 ; SSE-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
71 ; SSE:       vector.ph:
72 ; SSE-NEXT:    br label [[VECTOR_BODY:%.*]]
73 ; SSE:       vector.body:
74 ; SSE-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
75 ; SSE-NEXT:    [[VEC_PHI:%.*]] = phi <2 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[VECTOR_BODY]] ]
76 ; SSE-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
77 ; SSE-NEXT:    [[TMP1:%.*]] = getelementptr double, ptr [[ARR:%.*]], i32 [[TMP0]]
78 ; SSE-NEXT:    [[TMP2:%.*]] = getelementptr double, ptr [[TMP1]], i32 0
79 ; SSE-NEXT:    [[WIDE_LOAD:%.*]] = load <2 x double>, ptr [[TMP2]], align 8
80 ; SSE-NEXT:    [[TMP3:%.*]] = fcmp fast une <2 x double> [[WIDE_LOAD]], <double 4.200000e+01, double 4.200000e+01>
81 ; SSE-NEXT:    [[TMP5:%.*]] = xor <2 x i1> [[TMP3]], <i1 true, i1 true>
82 ; SSE-NEXT:    [[TMP4:%.*]] = fadd fast <2 x double> [[VEC_PHI]], [[WIDE_LOAD]]
83 ; SSE-NEXT:    [[PREDPHI]] = select <2 x i1> [[TMP3]], <2 x double> [[TMP4]], <2 x double> [[VEC_PHI]]
84 ; SSE-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 2
85 ; SSE-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 32
86 ; SSE-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
87 ; SSE:       middle.block:
88 ; SSE-NEXT:    [[TMP7:%.*]] = call fast double @llvm.vector.reduce.fadd.v2f64(double -0.000000e+00, <2 x double> [[PREDPHI]])
89 ; SSE-NEXT:    br i1 true, label [[DONE:%.*]], label [[SCALAR_PH]]
90 ; SSE:       scalar.ph:
91 ; SSE-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 32, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
92 ; SSE-NEXT:    [[BC_MERGE_RDX:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
93 ; SSE-NEXT:    br label [[LOOP:%.*]]
94 ; SSE:       loop:
95 ; SSE-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[I_NEXT:%.*]], [[NEXT_ITER:%.*]] ]
96 ; SSE-NEXT:    [[TOT:%.*]] = phi double [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[TOT_NEXT:%.*]], [[NEXT_ITER]] ]
97 ; SSE-NEXT:    [[ADDR:%.*]] = getelementptr double, ptr [[ARR]], i32 [[I]]
98 ; SSE-NEXT:    [[NEXTVAL:%.*]] = load double, ptr [[ADDR]], align 8
99 ; SSE-NEXT:    [[TST:%.*]] = fcmp fast une double [[NEXTVAL]], 4.200000e+01
100 ; SSE-NEXT:    br i1 [[TST]], label [[DO_ADD:%.*]], label [[NO_ADD:%.*]]
101 ; SSE:       do.add:
102 ; SSE-NEXT:    [[TOT_NEW:%.*]] = fadd fast double [[TOT]], [[NEXTVAL]]
103 ; SSE-NEXT:    br label [[NEXT_ITER]]
104 ; SSE:       no.add:
105 ; SSE-NEXT:    br label [[NEXT_ITER]]
106 ; SSE:       next.iter:
107 ; SSE-NEXT:    [[TOT_NEXT]] = phi double [ [[TOT]], [[NO_ADD]] ], [ [[TOT_NEW]], [[DO_ADD]] ]
108 ; SSE-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
109 ; SSE-NEXT:    [[AGAIN:%.*]] = icmp ult i32 [[I_NEXT]], 32
110 ; SSE-NEXT:    br i1 [[AGAIN]], label [[LOOP]], label [[DONE]], !llvm.loop [[LOOP2:![0-9]+]]
111 ; SSE:       done:
112 ; SSE-NEXT:    [[TOT_NEXT_LCSSA:%.*]] = phi double [ [[TOT_NEXT]], [[NEXT_ITER]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
113 ; SSE-NEXT:    ret double [[TOT_NEXT_LCSSA]]
115 ; AVX-LABEL: @sumIfVector(
116 ; AVX-NEXT:  entry:
117 ; AVX-NEXT:    br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]]
118 ; AVX:       vector.ph:
119 ; AVX-NEXT:    br label [[VECTOR_BODY:%.*]]
120 ; AVX:       vector.body:
121 ; AVX-NEXT:    [[INDEX:%.*]] = phi i32 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]
122 ; AVX-NEXT:    [[VEC_PHI:%.*]] = phi <4 x double> [ zeroinitializer, [[VECTOR_PH]] ], [ [[PREDPHI:%.*]], [[VECTOR_BODY]] ]
123 ; AVX-NEXT:    [[TMP0:%.*]] = add i32 [[INDEX]], 0
124 ; AVX-NEXT:    [[TMP1:%.*]] = getelementptr double, ptr [[ARR:%.*]], i32 [[TMP0]]
125 ; AVX-NEXT:    [[TMP2:%.*]] = getelementptr double, ptr [[TMP1]], i32 0
126 ; AVX-NEXT:    [[WIDE_LOAD:%.*]] = load <4 x double>, ptr [[TMP2]], align 8
127 ; AVX-NEXT:    [[TMP3:%.*]] = fcmp fast une <4 x double> [[WIDE_LOAD]], <double 4.200000e+01, double 4.200000e+01, double 4.200000e+01, double 4.200000e+01>
128 ; AVX-NEXT:    [[TMP5:%.*]] = xor <4 x i1> [[TMP3]], <i1 true, i1 true, i1 true, i1 true>
129 ; AVX-NEXT:    [[TMP4:%.*]] = fadd fast <4 x double> [[VEC_PHI]], [[WIDE_LOAD]]
130 ; AVX-NEXT:    [[PREDPHI]] = select <4 x i1> [[TMP3]], <4 x double> [[TMP4]], <4 x double> [[VEC_PHI]]
131 ; AVX-NEXT:    [[INDEX_NEXT]] = add nuw i32 [[INDEX]], 4
132 ; AVX-NEXT:    [[TMP6:%.*]] = icmp eq i32 [[INDEX_NEXT]], 32
133 ; AVX-NEXT:    br i1 [[TMP6]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]]
134 ; AVX:       middle.block:
135 ; AVX-NEXT:    [[TMP7:%.*]] = call fast double @llvm.vector.reduce.fadd.v4f64(double -0.000000e+00, <4 x double> [[PREDPHI]])
136 ; AVX-NEXT:    br i1 true, label [[DONE:%.*]], label [[SCALAR_PH]]
137 ; AVX:       scalar.ph:
138 ; AVX-NEXT:    [[BC_RESUME_VAL:%.*]] = phi i32 [ 32, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ]
139 ; AVX-NEXT:    [[BC_MERGE_RDX:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
140 ; AVX-NEXT:    br label [[LOOP:%.*]]
141 ; AVX:       loop:
142 ; AVX-NEXT:    [[I:%.*]] = phi i32 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[I_NEXT:%.*]], [[NEXT_ITER:%.*]] ]
143 ; AVX-NEXT:    [[TOT:%.*]] = phi double [ [[BC_MERGE_RDX]], [[SCALAR_PH]] ], [ [[TOT_NEXT:%.*]], [[NEXT_ITER]] ]
144 ; AVX-NEXT:    [[ADDR:%.*]] = getelementptr double, ptr [[ARR]], i32 [[I]]
145 ; AVX-NEXT:    [[NEXTVAL:%.*]] = load double, ptr [[ADDR]], align 8
146 ; AVX-NEXT:    [[TST:%.*]] = fcmp fast une double [[NEXTVAL]], 4.200000e+01
147 ; AVX-NEXT:    br i1 [[TST]], label [[DO_ADD:%.*]], label [[NO_ADD:%.*]]
148 ; AVX:       do.add:
149 ; AVX-NEXT:    [[TOT_NEW:%.*]] = fadd fast double [[TOT]], [[NEXTVAL]]
150 ; AVX-NEXT:    br label [[NEXT_ITER]]
151 ; AVX:       no.add:
152 ; AVX-NEXT:    br label [[NEXT_ITER]]
153 ; AVX:       next.iter:
154 ; AVX-NEXT:    [[TOT_NEXT]] = phi double [ [[TOT]], [[NO_ADD]] ], [ [[TOT_NEW]], [[DO_ADD]] ]
155 ; AVX-NEXT:    [[I_NEXT]] = add i32 [[I]], 1
156 ; AVX-NEXT:    [[AGAIN:%.*]] = icmp ult i32 [[I_NEXT]], 32
157 ; AVX-NEXT:    br i1 [[AGAIN]], label [[LOOP]], label [[DONE]], !llvm.loop [[LOOP2:![0-9]+]]
158 ; AVX:       done:
159 ; AVX-NEXT:    [[TOT_NEXT_LCSSA:%.*]] = phi double [ [[TOT_NEXT]], [[NEXT_ITER]] ], [ [[TMP7]], [[MIDDLE_BLOCK]] ]
160 ; AVX-NEXT:    ret double [[TOT_NEXT_LCSSA]]
162 entry:
163   br label %loop
165 loop:
166   %i = phi i32 [0, %entry], [%i.next, %next.iter]
167   %tot = phi double [0.0, %entry], [%tot.next, %next.iter]
169   %addr = getelementptr double, ptr %arr, i32 %i
170   %nextval = load double, ptr %addr
172   %tst = fcmp fast une double %nextval, 42.0
173   br i1 %tst, label %do.add, label %no.add
175 do.add:
176   %tot.new = fadd fast double %tot, %nextval
177   br label %next.iter
179 no.add:
180   br label %next.iter
182 next.iter:
183   %tot.next = phi double [%tot, %no.add], [%tot.new, %do.add]
184   %i.next = add i32 %i, 1
185   %again = icmp ult i32 %i.next, 32
186   br i1 %again, label %loop, label %done
188 done:
189   ret double %tot.next