[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / LoopVectorize / AArch64 / scalable-strict-fadd.ll
blobcba948ed1dae00fe4bc9e2d6ebe818720cd07f3a
1 ; RUN: opt < %s -loop-vectorize -scalable-vectorization=on -mtriple aarch64-unknown-linux-gnu -mattr=+sve -force-ordered-reductions=false -hints-allow-reordering=false -S 2>%t | FileCheck %s --check-prefix=CHECK-NOT-VECTORIZED
2 ; RUN: opt < %s -loop-vectorize -scalable-vectorization=on -mtriple aarch64-unknown-linux-gnu -mattr=+sve -force-ordered-reductions=false -hints-allow-reordering=true  -S 2>%t | FileCheck %s --check-prefix=CHECK-UNORDERED
3 ; RUN: opt < %s -loop-vectorize -scalable-vectorization=on -mtriple aarch64-unknown-linux-gnu -mattr=+sve -force-ordered-reductions=true  -hints-allow-reordering=false -S 2>%t | FileCheck %s --check-prefix=CHECK-ORDERED
4 ; RUN: opt < %s -loop-vectorize -scalable-vectorization=on -mtriple aarch64-unknown-linux-gnu -mattr=+sve -force-ordered-reductions=true  -hints-allow-reordering=true  -S 2>%t | FileCheck %s --check-prefix=CHECK-UNORDERED
5 ; RUN: opt < %s -loop-vectorize -scalable-vectorization=on -mtriple aarch64-unknown-linux-gnu -mattr=+sve -hints-allow-reordering=false -S 2>%t | FileCheck %s --check-prefix=CHECK-NOT-VECTORIZED
7 define float @fadd_strict(float* noalias nocapture readonly %a, i64 %n) #0 {
8 ; CHECK-ORDERED-LABEL: @fadd_strict
9 ; CHECK-ORDERED: vector.body:
10 ; CHECK-ORDERED: %[[VEC_PHI:.*]] = phi float [ 0.000000e+00, %vector.ph ], [ %[[RDX:.*]], %vector.body ]
11 ; CHECK-ORDERED: %[[LOAD:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
12 ; CHECK-ORDERED: %[[RDX]] = call float @llvm.vector.reduce.fadd.nxv8f32(float %[[VEC_PHI]], <vscale x 8 x float> %[[LOAD]])
13 ; CHECK-ORDERED: for.end
14 ; CHECK-ORDERED: %[[PHI:.*]] = phi float [ %[[SCALAR:.*]], %for.body ], [ %[[RDX]], %middle.block ]
15 ; CHECK-ORDERED: ret float %[[PHI]]
17 ; CHECK-UNORDERED-LABEL: @fadd_strict
18 ; CHECK-UNORDERED: vector.body
19 ; CHECK-UNORDERED: %[[VEC_PHI:.*]] = phi <vscale x 8 x float> [ insertelement (<vscale x 8 x float> shufflevector (<vscale x 8 x float> insertelement (<vscale x 8 x float> poison, float -0.000000e+00, i32 0), <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer), float 0.000000e+00, i32 0), %vector.ph ], [ %[[FADD_VEC:.*]], %vector.body ]
20 ; CHECK-UNORDERED: %[[LOAD_VEC:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
21 ; CHECK-UNORDERED: %[[FADD_VEC]] = fadd <vscale x 8 x float> %[[LOAD_VEC]], %[[VEC_PHI]]
22 ; CHECK-UNORDERED-NOT: call float @llvm.vector.reduce.fadd
23 ; CHECK-UNORDERED: middle.block
24 ; CHECK-UNORDERED: %[[RDX:.*]] = call float @llvm.vector.reduce.fadd.nxv8f32(float -0.000000e+00, <vscale x 8 x float> %[[FADD_VEC]])
25 ; CHECK-UNORDERED: for.body
26 ; CHECK-UNORDERED: %[[LOAD:.*]] = load float, float*
27 ; CHECK-UNORDERED: %[[FADD:.*]] = fadd float %[[LOAD]], {{.*}}
28 ; CHECK-UNORDERED: for.end
29 ; CHECK-UNORDERED: %[[RES:.*]] = phi float [ %[[FADD]], %for.body ], [ %[[RDX]], %middle.block ]
30 ; CHECK-UNORDERED: ret float %[[RES]]
32 ; CHECK-NOT-VECTORIZED-LABEL: @fadd_strict
33 ; CHECK-NOT-VECTORIZED-NOT: vector.body
35 entry:
36   br label %for.body
38 for.body:
39   %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
40   %sum.07 = phi float [ 0.000000e+00, %entry ], [ %add, %for.body ]
41   %arrayidx = getelementptr inbounds float, float* %a, i64 %iv
42   %0 = load float, float* %arrayidx, align 4
43   %add = fadd float %0, %sum.07
44   %iv.next = add nuw nsw i64 %iv, 1
45   %exitcond.not = icmp eq i64 %iv.next, %n
46   br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !0
48 for.end:
49   ret float %add
52 define float @fadd_strict_unroll(float* noalias nocapture readonly %a, i64 %n) #0 {
53 ; CHECK-ORDERED-LABEL: @fadd_strict_unroll
54 ; CHECK-ORDERED: vector.body:
55 ; CHECK-ORDERED: %[[VEC_PHI1:.*]] = phi float [ 0.000000e+00, %vector.ph ], [ %[[RDX4:.*]], %vector.body ]
56 ; CHECK-ORDERED-NOT: phi float [ 0.000000e+00, %vector.ph ], [ %[[RDX4]], %vector.body ]
57 ; CHECK-ORDERED: %[[LOAD1:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
58 ; CHECK-ORDERED: %[[LOAD2:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
59 ; CHECK-ORDERED: %[[LOAD3:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
60 ; CHECK-ORDERED: %[[LOAD4:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
61 ; CHECK-ORDERED: %[[RDX1:.*]] = call float @llvm.vector.reduce.fadd.nxv8f32(float %[[VEC_PHI1]], <vscale x 8 x float> %[[LOAD1]])
62 ; CHECK-ORDERED: %[[RDX2:.*]] = call float @llvm.vector.reduce.fadd.nxv8f32(float %[[RDX1]], <vscale x 8 x float> %[[LOAD2]])
63 ; CHECK-ORDERED: %[[RDX3:.*]] = call float @llvm.vector.reduce.fadd.nxv8f32(float %[[RDX2]], <vscale x 8 x float> %[[LOAD3]])
64 ; CHECK-ORDERED: %[[RDX4]] = call float @llvm.vector.reduce.fadd.nxv8f32(float %[[RDX3]], <vscale x 8 x float> %[[LOAD4]])
65 ; CHECK-ORDERED: for.end
66 ; CHECK-ORDERED: %[[PHI:.*]] = phi float [ %[[SCALAR:.*]], %for.body ], [ %[[RDX4]], %middle.block ]
67 ; CHECK-ORDERED: ret float %[[PHI]]
69 ; CHECK-UNORDERED-LABEL: @fadd_strict_unroll
70 ; CHECK-UNORDERED: vector.body
71 ; CHECK-UNORDERED: %[[VEC_PHI1:.*]] = phi <vscale x 8 x float> [ insertelement (<vscale x 8 x float> shufflevector (<vscale x 8 x float> insertelement (<vscale x 8 x float> poison, float -0.000000e+00, i32 0), <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer), float 0.000000e+00, i32 0), %vector.ph ], [ %[[VEC_FADD1:.*]], %vector.body ]
72 ; CHECK-UNORDERED: %[[VEC_PHI2:.*]] = phi <vscale x 8 x float> [ shufflevector (<vscale x 8 x float> insertelement (<vscale x 8 x float> poison, float -0.000000e+00, i32 0), <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer), %vector.ph ], [ %[[VEC_FADD2:.*]], %vector.body ]
73 ; CHECK-UNORDERED: %[[VEC_PHI3:.*]] = phi <vscale x 8 x float> [ shufflevector (<vscale x 8 x float> insertelement (<vscale x 8 x float> poison, float -0.000000e+00, i32 0), <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer), %vector.ph ], [ %[[VEC_FADD3:.*]], %vector.body ]
74 ; CHECK-UNORDERED: %[[VEC_PHI4:.*]] = phi <vscale x 8 x float> [ shufflevector (<vscale x 8 x float> insertelement (<vscale x 8 x float> poison, float -0.000000e+00, i32 0), <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer), %vector.ph ], [ %[[VEC_FADD4:.*]], %vector.body ]
75 ; CHECK-UNORDERED: %[[VEC_LOAD1:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
76 ; CHECK-UNORDERED: %[[VEC_LOAD2:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
77 ; CHECK-UNORDERED: %[[VEC_LOAD3:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
78 ; CHECK-UNORDERED: %[[VEC_LOAD4:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>*
79 ; CHECK-UNORDERED: %[[VEC_FADD1]] = fadd <vscale x 8 x float> %[[VEC_LOAD1]], %[[VEC_PHI1]]
80 ; CHECK-UNORDERED: %[[VEC_FADD2]] = fadd <vscale x 8 x float> %[[VEC_LOAD2]], %[[VEC_PHI2]]
81 ; CHECK-UNORDERED: %[[VEC_FADD3]] = fadd <vscale x 8 x float> %[[VEC_LOAD3]], %[[VEC_PHI3]]
82 ; CHECK-UNORDERED: %[[VEC_FADD4]] = fadd <vscale x 8 x float> %[[VEC_LOAD4]], %[[VEC_PHI4]]
83 ; CHECK-UNORDERED-NOT: call float @llvm.vector.reduce.fadd
84 ; CHECK-UNORDERED: middle.block
85 ; CHECK-UNORDERED: %[[BIN_RDX1:.*]] = fadd <vscale x 8 x float> %[[VEC_FADD2]], %[[VEC_FADD1]]
86 ; CHECK-UNORDERED: %[[BIN_RDX2:.*]] = fadd <vscale x 8 x float> %[[VEC_FADD3]], %[[BIN_RDX1]]
87 ; CHECK-UNORDERED: %[[BIN_RDX3:.*]] = fadd <vscale x 8 x float> %[[VEC_FADD4]], %[[BIN_RDX2]]
88 ; CHECK-UNORDERED: %[[RDX:.*]] = call float @llvm.vector.reduce.fadd.nxv8f32(float -0.000000e+00, <vscale x 8 x float> %[[BIN_RDX3]])
89 ; CHECK-UNORDERED: for.body
90 ; CHECK-UNORDERED: %[[LOAD:.*]] = load float, float*
91 ; CHECK-UNORDERED: %[[FADD:.*]] = fadd float %[[LOAD]], {{.*}}
92 ; CHECK-UNORDERED: for.end
93 ; CHECK-UNORDERED: %[[RES:.*]] = phi float [ %[[FADD]], %for.body ], [ %[[RDX]], %middle.block ]
94 ; CHECK-UNORDERED: ret float %[[RES]]
96 ; CHECK-NOT-VECTORIZED-LABEL: @fadd_strict_unroll
97 ; CHECK-NOT-VECTORIZED-NOT: vector.body
99 entry:
100   br label %for.body
102 for.body:
103   %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
104   %sum.07 = phi float [ 0.000000e+00, %entry ], [ %add, %for.body ]
105   %arrayidx = getelementptr inbounds float, float* %a, i64 %iv
106   %0 = load float, float* %arrayidx, align 4
107   %add = fadd float %0, %sum.07
108   %iv.next = add nuw nsw i64 %iv, 1
109   %exitcond.not = icmp eq i64 %iv.next, %n
110   br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !1
112 for.end:
113   ret float %add
116 define void @fadd_strict_interleave(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
117 ; CHECK-ORDERED-LABEL: @fadd_strict_interleave
118 ; CHECK-ORDERED: entry
119 ; CHECK-ORDERED: %[[ARRAYIDX:.*]] = getelementptr inbounds float, float* %a, i64 1
120 ; CHECK-ORDERED: %[[LOAD1:.*]] = load float, float* %a
121 ; CHECK-ORDERED: %[[LOAD2:.*]] = load float, float* %[[ARRAYIDX]]
122 ; CHECK-ORDERED: vector.ph
123 ; CHECK-ORDERED: %[[STEPVEC1:.*]] = call <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
124 ; CHECK-ORDERED: %[[STEPVEC_ADD1:.*]] = add <vscale x 4 x i64> %[[STEPVEC1]], shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 0, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer)
125 ; CHECK-ORDERED: %[[STEPVEC_MUL:.*]] = mul <vscale x 4 x i64> %[[STEPVEC_ADD1]], shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 2, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer)
126 ; CHECK-ORDERED: %[[INDUCTION:.*]] = add <vscale x 4 x i64> shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 0, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer), %[[STEPVEC_MUL]]
127 ; CHECK-ORDERED: vector.body
128 ; CHECK-ORDERED: %[[VEC_PHI2:.*]] = phi float [ %[[LOAD2]], %vector.ph ], [ %[[RDX2:.*]], %vector.body ]
129 ; CHECK-ORDERED: %[[VEC_PHI1:.*]] = phi float [ %[[LOAD1]], %vector.ph ], [ %[[RDX1:.*]], %vector.body ]
130 ; CHECK-ORDERED: %[[VEC_IND:.*]] = phi <vscale x 4 x i64> [ %[[INDUCTION]], %vector.ph ], [ {{.*}}, %vector.body ]
131 ; CHECK-ORDERED: %[[GEP1:.*]] = getelementptr inbounds float, float* %b, <vscale x 4 x i64> %[[VEC_IND]]
132 ; CHECK-ORDERED: %[[MGATHER1:.*]] = call <vscale x 4 x float> @llvm.masked.gather.nxv4f32.nxv4p0f32(<vscale x 4 x float*> %[[GEP1]], i32 4, <vscale x 4 x i1> shufflevector (<vscale x 4 x i1> insertelement (<vscale x 4 x i1> poison, i1 true, i32 0), <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> undef)
133 ; CHECK-ORDERED: %[[RDX1]] = call float @llvm.vector.reduce.fadd.nxv4f32(float %[[VEC_PHI1]], <vscale x 4 x float> %[[MGATHER1]])
134 ; CHECK-ORDERED: %[[OR:.*]] = or <vscale x 4 x i64> %[[VEC_IND]], shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 1, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer)
135 ; CHECK-ORDERED: %[[GEP2:.*]] = getelementptr inbounds float, float* %b, <vscale x 4 x i64> %[[OR]]
136 ; CHECK-ORDERED: %[[MGATHER2:.*]] = call <vscale x 4 x float> @llvm.masked.gather.nxv4f32.nxv4p0f32(<vscale x 4 x float*> %[[GEP2]], i32 4, <vscale x 4 x i1> shufflevector (<vscale x 4 x i1> insertelement (<vscale x 4 x i1> poison, i1 true, i32 0), <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> undef)
137 ; CHECK-ORDERED: %[[RDX2]] = call float @llvm.vector.reduce.fadd.nxv4f32(float %[[VEC_PHI2]], <vscale x 4 x float> %[[MGATHER2]])
138 ; CHECK-ORDERED: for.end
139 ; CHECK-ORDERED: ret void
141 ; CHECK-UNORDERED-LABEL: @fadd_strict_interleave
142 ; CHECK-UNORDERED: entry
143 ; CHECK-UNORDERED: %[[ARRAYIDX:.*]] = getelementptr inbounds float, float* %a, i64 1
144 ; CHECK-UNORDERED: %[[LOAD1:.*]] = load float, float* %a
145 ; CHECK-UNORDERED: %[[LOAD2:.*]] = load float, float* %[[ARRAYIDX]]
146 ; CHECK-UNORDERED: vector.ph
147 ; CHECK-UNORDERED: %[[INS_ELT2:.*]] = insertelement <vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float -0.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), float %[[LOAD2]], i32 0
148 ; CHECK-UNORDERED: %[[INS_ELT1:.*]] = insertelement <vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float -0.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), float %[[LOAD1]], i32 0
149 ; CHECK-UNORDERED: %[[STEPVEC1:.*]] = call <vscale x 4 x i64> @llvm.experimental.stepvector.nxv4i64()
150 ; CHECK-UNORDERED: %[[STEPVEC_ADD1:.*]] = add <vscale x 4 x i64> %[[STEPVEC1]], shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 0, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer)
151 ; CHECK-UNORDERED: %[[STEPVEC_MUL:.*]] = mul <vscale x 4 x i64> %[[STEPVEC_ADD1]], shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 2, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer)
152 ; CHECK-UNORDERED: %[[INDUCTION:.*]] = add <vscale x 4 x i64> shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 0, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer), %[[STEPVEC_MUL]]
153 ; CHECK-UNORDERED: vector.body
154 ; CHECK-UNORDERED: %[[VEC_PHI2:.*]] = phi <vscale x 4 x float> [ %[[INS_ELT2]], %vector.ph ], [ %[[VEC_FADD2:.*]], %vector.body ]
155 ; CHECK-UNORDERED: %[[VEC_PHI1:.*]] = phi <vscale x 4 x float> [ %[[INS_ELT1]], %vector.ph ], [ %[[VEC_FADD1:.*]], %vector.body ]
156 ; CHECK-UNORDERED: %[[GEP1:.*]] = getelementptr inbounds float, float* %b, <vscale x 4 x i64>
157 ; CHECK-UNORDERED: %[[MGATHER1:.*]] = call <vscale x 4 x float> @llvm.masked.gather.nxv4f32.nxv4p0f32(<vscale x 4 x float*> %[[GEP1]], i32 4, <vscale x 4 x i1> shufflevector (<vscale x 4 x i1> insertelement (<vscale x 4 x i1> poison, i1 true, i32 0), <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> undef)
158 ; CHECK-UNORDERED:  %[[VEC_FADD1]] = fadd <vscale x 4 x float> %[[MGATHER1]], %[[VEC_PHI1]]
159 ; CHECK-UNORDERED: %[[OR:.*]] = or <vscale x 4 x i64> {{.*}}, shufflevector (<vscale x 4 x i64> insertelement (<vscale x 4 x i64> poison, i64 1, i32 0), <vscale x 4 x i64> poison, <vscale x 4 x i32> zeroinitializer)
160 ; CHECK-UNORDERED: %[[GEP2:.*]] = getelementptr inbounds float, float* %b, <vscale x 4 x i64> %[[OR]]
161 ; CHECK-UNORDERED: %[[MGATHER2:.*]] = call <vscale x 4 x float> @llvm.masked.gather.nxv4f32.nxv4p0f32(<vscale x 4 x float*> %[[GEP2]], i32 4, <vscale x 4 x i1> shufflevector (<vscale x 4 x i1> insertelement (<vscale x 4 x i1> poison, i1 true, i32 0), <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> undef)
162 ; CHECK-UNORDERED: %[[VEC_FADD2]] = fadd <vscale x 4 x float> %[[MGATHER2]], %[[VEC_PHI2]]
163 ; CHECK-UNORDERED-NOT: call float @llvm.vector.reduce.fadd
164 ; CHECK-UNORDERED: middle.block
165 ; CHECK-UNORDERED: %[[VEC_RDX1:.*]] = call float @llvm.vector.reduce.fadd.nxv4f32(float -0.000000e+00, <vscale x 4 x float> %[[VEC_FADD1]])
166 ; CHECK-UNORDERED: %[[VEC_RDX2:.*]] = call float @llvm.vector.reduce.fadd.nxv4f32(float -0.000000e+00, <vscale x 4 x float> %[[VEC_FADD2]])
167 ; CHECK-UNORDERED: for.body
168 ; CHECK-UNORDERED: %[[LOAD3:.*]] = load float, float*
169 ; CHECK-UNORDERED: %[[FADD1:.*]] = fadd float %[[LOAD3]], {{.*}}
170 ; CHECK-UNORDERED: %[[LOAD4:.*]] = load float, float*
171 ; CHECK-UNORDERED: %[[FADD2:.*]] = fadd float %[[LOAD4]], {{.*}}
172 ; CHECK-UNORDERED: for.end
173 ; CHECK-UNORDERED: %[[RDX1:.*]] = phi float [ %[[FADD1]], %for.body ], [ %[[VEC_RDX1]], %middle.block ]
174 ; CHECK-UNORDERED: %[[RDX2:.*]] = phi float [ %[[FADD2]], %for.body ], [ %[[VEC_RDX2]], %middle.block ]
175 ; CHECK-UNORDERED: store float %[[RDX1]], float* %a
176 ; CHECK-UNORDERED: store float %[[RDX2]], float* {{.*}}
177 ; CHECK-UNORDERED: ret void
179 ; CHECK-NOT-VECTORIZED-LABEL: @fadd_strict_interleave
180 ; CHECK-NOT-VECTORIZED-NOT: vector.body
182 entry:
183   %arrayidxa = getelementptr inbounds float, float* %a, i64 1
184   %a1 = load float, float* %a, align 4
185   %a2 = load float, float* %arrayidxa, align 4
186   br label %for.body
188 for.body:
189   %add.phi1 = phi float [ %a2, %entry ], [ %add2, %for.body ]
190   %add.phi2 = phi float [ %a1, %entry ], [ %add1, %for.body ]
191   %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
192   %arrayidxb1 = getelementptr inbounds float, float* %b, i64 %iv
193   %0 = load float, float* %arrayidxb1, align 4
194   %add1 = fadd float %0, %add.phi2
195   %or = or i64 %iv, 1
196   %arrayidxb2 = getelementptr inbounds float, float* %b, i64 %or
197   %1 = load float, float* %arrayidxb2, align 4
198   %add2 = fadd float %1, %add.phi1
199   %iv.next = add nuw nsw i64 %iv, 2
200   %exitcond.not = icmp eq i64 %iv.next, %n
201   br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !2
203 for.end:
204   store float %add1, float* %a, align 4
205   store float %add2, float* %arrayidxa, align 4
206   ret void
209 define float @fadd_of_sum(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
210 ; CHECK-ORDERED-LABEL: @fadd_of_sum
211 ; CHECK-ORDERED: vector.body
212 ; CHECK-ORDERED: %[[VEC_PHI1:.*]] = phi float [ 0.000000e+00, %vector.ph ], [ %[[RDX:.*]], %vector.body ]
213 ; CHECK-ORDERED: %[[LOAD1:.*]] = load <vscale x 4 x float>, <vscale x 4 x float>*
214 ; CHECK-ORDERED: %[[LOAD2:.*]] = load <vscale x 4 x float>, <vscale x 4 x float>*
215 ; CHECK-ORDERED: %[[ADD:.*]] = fadd <vscale x 4 x float> %[[LOAD1]], %[[LOAD2]]
216 ; CHECK-ORDERED: %[[RDX]] = call float @llvm.vector.reduce.fadd.nxv4f32(float %[[VEC_PHI1]], <vscale x 4 x float> %[[ADD]])
217 ; CHECK-ORDERED: for.end.loopexit
218 ; CHECK-ORDERED: %[[EXIT_PHI:.*]] = phi float [ {{.*}}, %for.body ], [ %[[RDX]], %middle.block ]
219 ; CHECK-ORDERED: for.end
220 ; CHECK-ORDERED: %[[PHI:.*]] = phi float [ 0.000000e+00, %entry ], [ %[[EXIT_PHI]], %for.end.loopexit ]
221 ; CHECK-ORDERED: ret float %[[PHI]]
223 ; CHECK-UNORDERED-LABEL: @fadd_of_sum
224 ; CHECK-UNORDERED: vector.body
225 ; CHECK-UNORDERED: %[[VEC_PHI:.*]] = phi <vscale x 4 x float> [ insertelement (<vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float -0.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), float 0.000000e+00, i32 0), %vector.ph ], [ %[[VEC_FADD2:.*]], %vector.body ]
226 ; CHECK-UNORDERED: %[[VEC_LOAD1:.*]] = load <vscale x 4 x float>, <vscale x 4 x float>*
227 ; CHECK-UNORDERED: %[[VEC_LOAD2:.*]] = load <vscale x 4 x float>, <vscale x 4 x float>*
228 ; CHECK-UNORDERED: %[[VEC_FADD1:.*]] = fadd <vscale x 4 x float> %[[VEC_LOAD1]], %[[VEC_LOAD2]]
229 ; CHECK-UNORDERED: %[[VEC_FADD2]] = fadd <vscale x 4 x float> %[[VEC_PHI]], %[[VEC_FADD1]]
230 ; CHECK-UNORDERED-NOT: call float @llvm.vector.reduce.fadd
231 ; CHECK-UNORDERED: middle.block
232 ; CHECK-UNORDERED: %[[RDX:.*]] = call float @llvm.vector.reduce.fadd.nxv4f32(float -0.000000e+00, <vscale x 4 x float> %[[VEC_FADD2]])
233 ; CHECK-UNORDERED: for.body
234 ; CHECK-UNORDERED: %[[LOAD1:.*]] = load float, float*
235 ; CHECK-UNORDERED: %[[LOAD2:.*]] = load float, float*
236 ; CHECK-UNORDERED: %[[FADD1:.*]] = fadd float %[[LOAD1]], %[[LOAD2]]
237 ; CHECK-UNORDERED: %[[FADD2:.*]] = fadd float {{.*}}, %[[FADD1]]
238 ; CHECK-UNORDERED: for.end.loopexit
239 ; CHECK-UNORDERED: %[[EXIT:.*]] = phi float [ %[[FADD2]], %for.body ], [ %[[RDX]], %middle.block ]
240 ; CHECK-UNORDERED: for.end
241 ; CHECK-UNORDERED: %[[SUM:.*]] = phi float [ 0.000000e+00, %entry ], [ %[[EXIT]], %for.end.loopexit ]
242 ; CHECK-UNORDERED: ret float %[[SUM]]
244 ; CHECK-NOT-VECTORIZED-LABEL: @fadd_of_sum
245 ; CHECK-NOT-VECTORIZED-NOT: vector.body
247 entry:
248   %arrayidx = getelementptr inbounds float, float* %a, i64 1
249   %0 = load float, float* %arrayidx, align 4
250   %cmp1 = fcmp ogt float %0, 5.000000e-01
251   br i1 %cmp1, label %for.body, label %for.end
253 for.body:                                      ; preds = %for.body
254   %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
255   %res.014 = phi float [ 0.000000e+00, %entry ], [ %rdx, %for.body ]
256   %arrayidx2 = getelementptr inbounds float, float* %a, i64 %iv
257   %1 = load float, float* %arrayidx2, align 4
258   %arrayidx4 = getelementptr inbounds float, float* %b, i64 %iv
259   %2 = load float, float* %arrayidx4, align 4
260   %add = fadd float %1, %2
261   %rdx = fadd float %res.014, %add
262   %iv.next = add nuw nsw i64 %iv, 1
263   %exitcond.not = icmp eq i64 %iv.next, %n
264   br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !2
266 for.end:                                 ; preds = %for.body, %entry
267   %res = phi float [ 0.000000e+00, %entry ], [ %rdx, %for.body ]
268   ret float %res
271 define float @fadd_conditional(float* noalias nocapture readonly %a, float* noalias nocapture readonly %b, i64 %n) #0 {
272 ; CHECK-ORDERED-LABEL: @fadd_conditional
273 ; CHECK-ORDERED: vector.body
274 ; CHECK-ORDERED: %[[VEC_PHI:.*]] = phi float [ 1.000000e+00, %vector.ph ], [ %[[RDX:.*]], %vector.body ]
275 ; CHECK-ORDERED: %[[LOAD:.*]] = load <vscale x 4 x float>, <vscale x 4 x float>*
276 ; CHECK-ORDERED: %[[FCMP:.*]] = fcmp une <vscale x 4 x float> %[[LOAD]], shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 0.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer)
277 ; CHECK-ORDERED: %[[MASKED_LOAD:.*]] = call <vscale x 4 x float> @llvm.masked.load.nxv4f32.p0nxv4f32(<vscale x 4 x float>* {{.*}}, i32 4, <vscale x 4 x i1> %[[FCMP]], <vscale x 4 x float> poison)
278 ; CHECK-ORDERED: %[[XOR:.*]] = xor <vscale x 4 x i1> %[[FCMP]], shufflevector (<vscale x 4 x i1> insertelement (<vscale x 4 x i1> poison, i1 true, i32 0), <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer)
279 ; CHECK-ORDERED: %[[SELECT:.*]] = select <vscale x 4 x i1> %[[XOR]], <vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 3.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> %[[MASKED_LOAD]]
280 ; CHECK-ORDERED: %[[RDX]] = call float @llvm.vector.reduce.fadd.nxv4f32(float %[[VEC_PHI]], <vscale x 4 x float> %[[SELECT]])
281 ; CHECK-ORDERED: scalar.ph
282 ; CHECK-ORDERED: %[[MERGE_RDX:.*]] = phi float [ 1.000000e+00, %entry ], [ %[[RDX]], %middle.block ]
283 ; CHECK-ORDERED: for.body
284 ; CHECK-ORDERED: %[[RES:.*]] = phi float [ %[[MERGE_RDX]], %scalar.ph ], [ %[[FADD:.*]], %for.inc ]
285 ; CHECK-ORDERED: if.then
286 ; CHECK-ORDERED: %[[LOAD2:.*]] = load float, float*
287 ; CHECK-ORDERED: for.inc
288 ; CHECK-ORDERED: %[[PHI:.*]] = phi float [ %[[LOAD2]], %if.then ], [ 3.000000e+00, %for.body ]
289 ; CHECK-ORDERED: %[[FADD]] = fadd float %[[RES]], %[[PHI]]
290 ; CHECK-ORDERED: for.end
291 ; CHECK-ORDERED: %[[RDX_PHI:.*]] = phi float [ %[[FADD]], %for.inc ], [ %[[RDX]], %middle.block ]
292 ; CHECK-ORDERED: ret float %[[RDX_PHI]]
294 ; CHECK-UNORDERED-LABEL: @fadd_conditional
295 ; CHECK-UNORDERED: vector.body
296 ; CHECK-UNORDERED: %[[VEC_PHI:.*]] = phi <vscale x 4 x float> [ insertelement (<vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float -0.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), float 1.000000e+00, i32 0), %vector.ph ], [ %[[VEC_FADD:.*]], %vector.body ]
297 ; CHECK-UNORDERED: %[[LOAD1:.*]] = load <vscale x 4 x float>, <vscale x 4 x float>*
298 ; CHECK-UNORDERED: %[[FCMP:.*]] = fcmp une <vscale x 4 x float> %[[LOAD1]], shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 0.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer)
299 ; CHECK-UNORDERED: %[[MASKED_LOAD:.*]] = call <vscale x 4 x float> @llvm.masked.load.nxv4f32.p0nxv4f32(<vscale x 4 x float>* {{.*}}, i32 4, <vscale x 4 x i1> %[[FCMP]], <vscale x 4 x float> poison)
300 ; CHECK-UNORDERED: %[[XOR:.*]] = xor <vscale x 4 x i1> %[[FCMP]], shufflevector (<vscale x 4 x i1> insertelement (<vscale x 4 x i1> poison, i1 true, i32 0), <vscale x 4 x i1> poison, <vscale x 4 x i32> zeroinitializer)
301 ; CHECK-UNORDERED: %[[SELECT:.*]] = select <vscale x 4 x i1> %[[XOR]], <vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 3.000000e+00, i32 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> %[[MASKED_LOAD]]
302 ; CHECK-UNORDERED: %[[VEC_FADD]] = fadd <vscale x 4 x float> %[[VEC_PHI]], %[[SELECT]]
303 ; CHECK-UNORDERED-NOT: call float @llvm.vector.reduce.fadd
304 ; CHECK-UNORDERED: middle.block
305 ; CHECK-UNORDERED: %[[RDX:.*]] = call float @llvm.vector.reduce.fadd.nxv4f32(float -0.000000e+00, <vscale x 4 x float> %[[VEC_FADD]])
306 ; CHECK-UNORDERED: for.body
307 ; CHECK-UNORDERED: %[[RES:.*]] = phi float [ %bc.merge.rdx, %scalar.ph ], [ %[[FADD:.*]], %for.inc ]
308 ; CHECK-UNORDERED: for.inc
309 ; CHECK-UNORDERED: %[[FADD]] = fadd float %[[RES]], {{.*}}
310 ; CHECK-UNORDERED: for.end
311 ; CHECK-UNORDERED: %[[RDX_PHI:.*]] = phi float [ %[[FADD]], %for.inc ], [ %[[RDX]], %middle.block ]
312 ; CHECK-UNORDERED: ret float %[[RDX_PHI]]
314 ; CHECK-NOT-VECTORIZED-LABEL: @fadd_conditional
315 ; CHECK-NOT-VECTORIZED-NOT: vector.body
317 entry:
318   br label %for.body
320 for.body:                                      ; preds = %for.body
321   %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.inc ]
322   %res = phi float [ 1.000000e+00, %entry ], [ %fadd, %for.inc ]
323   %arrayidx = getelementptr inbounds float, float* %b, i64 %iv
324   %0 = load float, float* %arrayidx, align 4
325   %tobool = fcmp une float %0, 0.000000e+00
326   br i1 %tobool, label %if.then, label %for.inc
328 if.then:                                      ; preds = %for.body
329   %arrayidx2 = getelementptr inbounds float, float* %a, i64 %iv
330   %1 = load float, float* %arrayidx2, align 4
331   br label %for.inc
333 for.inc:
334   %phi = phi float [ %1, %if.then ], [ 3.000000e+00, %for.body ]
335   %fadd = fadd float %res, %phi
336   %iv.next = add nuw nsw i64 %iv, 1
337   %exitcond.not = icmp eq i64 %iv.next, %n
338   br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !2
340 for.end:
341   %rdx = phi float [ %fadd, %for.inc ]
342   ret float %rdx
345 ; Negative test - loop contains multiple fadds which we cannot safely reorder
346 define float @fadd_multiple(float* noalias nocapture %a, float* noalias nocapture %b, i64 %n) #0 {
347 ; CHECK-ORDERED-LABEL: @fadd_multiple
348 ; CHECK-ORDERED-NOT: vector.body
350 ; CHECK-UNORDERED-LABEL: @fadd_multiple
351 ; CHECK-UNORDERED: vector.body
352 ; CHECK-UNORDERED: %[[PHI:.*]] = phi <vscale x 8 x float> [ insertelement (<vscale x 8 x float> shufflevector (<vscale x 8 x float> insertelement (<vscale x 8 x float> poison, float -0.000000e+00, i32 0), <vscale x 8 x float> poison, <vscale x 8 x i32> zeroinitializer), float -0.000000e+00, i32 0), %vector.ph ], [ %[[VEC_FADD2:.*]], %vector.body ]
353 ; CHECK-UNORDERED: %[[VEC_LOAD1:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>
354 ; CHECK-UNORDERED: %[[VEC_FADD1:.*]] = fadd <vscale x 8 x float> %[[PHI]], %[[VEC_LOAD1]]
355 ; CHECK-UNORDERED: %[[VEC_LOAD2:.*]] = load <vscale x 8 x float>, <vscale x 8 x float>
356 ; CHECK-UNORDERED: %[[VEC_FADD2]] = fadd <vscale x 8 x float> %[[VEC_FADD1]], %[[VEC_LOAD2]]
357 ; CHECK-UNORDERED: middle.block
358 ; CHECK-UNORDERED: %[[RDX:.*]] = call float @llvm.vector.reduce.fadd.nxv8f32(float -0.000000e+00, <vscale x 8 x float> %[[VEC_FADD2]])
359 ; CHECK-UNORDERED: for.body
360 ; CHECK-UNORDERED: %[[SUM:.*]] = phi float [ %bc.merge.rdx, %scalar.ph ], [ %[[FADD2:.*]], %for.body ]
361 ; CHECK-UNORDERED: %[[LOAD1:.*]] = load float, float*
362 ; CHECK-UNORDERED: %[[FADD1:.*]] = fadd float %[[SUM]], %[[LOAD1]]
363 ; CHECK-UNORDERED: %[[LOAD2:.*]] = load float, float*
364 ; CHECK-UNORDERED: %[[FADD2]] = fadd float %[[FADD1]], %[[LOAD2]]
365 ; CHECK-UNORDERED: for.end
366 ; CHECK-UNORDERED: %[[RET:.*]] = phi float [ %[[FADD2]], %for.body ], [ %[[RDX]], %middle.block ]
367 ; CHECK-UNORDERED: ret float %[[RET]]
369 ; CHECK-NOT-VECTORIZED-LABEL: @fadd_multiple
370 ; CHECK-NOT-VECTORIZED-NOT: vector.body
372 entry:
373   br label %for.body
375 for.body:                                         ; preds = %entry, %for.body
376   %iv = phi i64 [ 0, %entry ], [ %iv.next, %for.body ]
377   %sum = phi float [ -0.000000e+00, %entry ], [ %add3, %for.body ]
378   %arrayidx = getelementptr inbounds float, float* %a, i64 %iv
379   %0 = load float, float* %arrayidx, align 4
380   %add = fadd float %sum, %0
381   %arrayidx2 = getelementptr inbounds float, float* %b, i64 %iv
382   %1 = load float, float* %arrayidx2, align 4
383   %add3 = fadd float %add, %1
384   %iv.next = add nuw nsw i64 %iv, 1
385   %exitcond.not = icmp eq i64 %iv.next, %n
386   br i1 %exitcond.not, label %for.end, label %for.body, !llvm.loop !0
388 for.end:                                         ; preds = %for.body
389   %rdx = phi float [ %add3, %for.body ]
390   ret float %rdx
393 attributes #0 = { vscale_range(0, 16) }
394 !0 = distinct !{!0, !3, !6, !8}
395 !1 = distinct !{!1, !3, !7, !8}
396 !2 = distinct !{!2, !4, !6, !8}
397 !3 = !{!"llvm.loop.vectorize.width", i32 8}
398 !4 = !{!"llvm.loop.vectorize.width", i32 4}
399 !5 = !{!"llvm.loop.vectorize.width", i32 2}
400 !6 = !{!"llvm.loop.interleave.count", i32 1}
401 !7 = !{!"llvm.loop.interleave.count", i32 4}
402 !8 = !{!"llvm.loop.vectorize.scalable.enable", i1 true}