Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / fadd.ll
blob38508cdb09e1f0d0ba258faa68b622c66afcced2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 declare void @use(float)
5 declare void @use_vec(<2 x float>)
6 declare float @llvm.vector.reduce.fadd.v4f32(float, <4 x float>)
8 ; -x + y => y - x
10 define float @fneg_op0(float %x, float %y) {
11 ; CHECK-LABEL: @fneg_op0(
12 ; CHECK-NEXT:    [[ADD:%.*]] = fsub float [[Y:%.*]], [[X:%.*]]
13 ; CHECK-NEXT:    ret float [[ADD]]
15   %neg = fsub float -0.0, %x
16   %add = fadd float %neg, %y
17   ret float %add
20 ; x + -y => x - y
22 define float @fneg_op1(float %x, float %y) {
23 ; CHECK-LABEL: @fneg_op1(
24 ; CHECK-NEXT:    [[ADD:%.*]] = fsub float [[X:%.*]], [[Y:%.*]]
25 ; CHECK-NEXT:    ret float [[ADD]]
27   %neg = fsub float -0.0, %y
28   %add = fadd float %x, %neg
29   ret float %add
32 ; Z + (-X / Y) --> Z - (X / Y)
34 define double @fdiv_fneg1(double %x, double %y, double %pz) {
35 ; CHECK-LABEL: @fdiv_fneg1(
36 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
37 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
38 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
39 ; CHECK-NEXT:    ret double [[R]]
41   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
42   %neg = fsub double -0.000000e+00, %x
43   %div = fdiv double %neg, %y
44   %r = fadd double %z, %div
45   ret double %r
48 ; Z + (Y / -X) --> Z - (Y / X)
50 define <2 x double> @fdiv_fneg2(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {
51 ; CHECK-LABEL: @fdiv_fneg2(
52 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x double> <double 4.200000e+01, double 8.000000e+00>, [[PZ:%.*]]
53 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]
54 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]
55 ; CHECK-NEXT:    ret <2 x double> [[R]]
57   %z = frem <2 x double> <double 42.0, double 8.0>, %pz ; thwart complexity-based canonicalization
58   %neg = fsub <2 x double> <double -0.0, double -0.0>, %x
59   %div = fdiv <2 x double> %y, %neg
60   %r = fadd <2 x double> %z, %div
61   ret <2 x double> %r
64 ; Z + (-X * Y) --> Z - (X * Y)
66 define double @fmul_fneg1(double %x, double %y, double %pz) {
67 ; CHECK-LABEL: @fmul_fneg1(
68 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
69 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]
70 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
71 ; CHECK-NEXT:    ret double [[R]]
73   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
74   %neg = fsub double -0.000000e+00, %x
75   %mul = fmul double %neg, %y
76   %r = fadd double %z, %mul
77   ret double %r
80 ; Z + (Y * -X) --> Z - (Y * X)
82 define double @fmul_fneg2(double %x, double %py, double %pz) {
83 ; CHECK-LABEL: @fmul_fneg2(
84 ; CHECK-NEXT:    [[Y:%.*]] = frem double -4.200000e+01, [[PY:%.*]]
85 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
86 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[Y]], [[X:%.*]]
87 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
88 ; CHECK-NEXT:    ret double [[R]]
90   %y = frem double -42.0, %py ; thwart complexity-based canonicalization
91   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
92   %neg = fsub double -0.000000e+00, %x
93   %mul = fmul double %y, %neg
94   %r = fadd double %z, %mul
95   ret double %r
98 ; (-X / Y) + Z --> Z - (X / Y)
100 define double @fdiv_fneg1_commute(double %x, double %y, double %pz) {
101 ; CHECK-LABEL: @fdiv_fneg1_commute(
102 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
103 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv double [[X:%.*]], [[Y:%.*]]
104 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
105 ; CHECK-NEXT:    ret double [[R]]
107   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
108   %neg = fsub double -0.000000e+00, %x
109   %div = fdiv double %neg, %y
110   %r = fadd double %div, %z
111   ret double %r
114 ; (Y / -X) + Z --> Z - (Y / X)
116 define <2 x double> @fdiv_fneg2_commute(<2 x double> %x, <2 x double> %y, <2 x double> %pz) {
117 ; CHECK-LABEL: @fdiv_fneg2_commute(
118 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x double> <double 4.200000e+01, double 8.000000e+00>, [[PZ:%.*]]
119 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv <2 x double> [[Y:%.*]], [[X:%.*]]
120 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x double> [[Z]], [[TMP1]]
121 ; CHECK-NEXT:    ret <2 x double> [[R]]
123   %z = frem <2 x double> <double 42.0, double 8.0>, %pz ; thwart complexity-based canonicalization
124   %neg = fsub <2 x double> <double -0.0, double -0.0>, %x
125   %div = fdiv <2 x double> %y, %neg
126   %r = fadd <2 x double> %div, %z
127   ret <2 x double> %r
130 ; (-X * Y) + Z --> Z - (X * Y)
132 define double @fmul_fneg1_commute(double %x, double %y, double %pz) {
133 ; CHECK-LABEL: @fmul_fneg1_commute(
134 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
135 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[X:%.*]], [[Y:%.*]]
136 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
137 ; CHECK-NEXT:    ret double [[R]]
139   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
140   %neg = fsub double -0.000000e+00, %x
141   %mul = fmul double %neg, %y
142   %r = fadd double %mul, %z
143   ret double %r
146 ; (Y * -X) + Z --> Z - (Y * X)
148 define double @fmul_fneg2_commute(double %x, double %py, double %pz) {
149 ; CHECK-LABEL: @fmul_fneg2_commute(
150 ; CHECK-NEXT:    [[Y:%.*]] = frem double 4.100000e+01, [[PY:%.*]]
151 ; CHECK-NEXT:    [[Z:%.*]] = frem double 4.200000e+01, [[PZ:%.*]]
152 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul double [[Y]], [[X:%.*]]
153 ; CHECK-NEXT:    [[R:%.*]] = fsub double [[Z]], [[TMP1]]
154 ; CHECK-NEXT:    ret double [[R]]
156   %y = frem double 41.0, %py ; thwart complexity-based canonicalization
157   %z = frem double 42.0, %pz ; thwart complexity-based canonicalization
158   %neg = fsub double -0.000000e+00, %x
159   %mul = fmul double %y, %neg
160   %r = fadd double %mul, %z
161   ret double %r
164 ; Z + (-X / Y) - extra use means we can't transform to fsub without an extra instruction
166 define float @fdiv_fneg1_extra_use(float %x, float %y, float %pz) {
167 ; CHECK-LABEL: @fdiv_fneg1_extra_use(
168 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
169 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
170 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
171 ; CHECK-NEXT:    call void @use(float [[DIV]])
172 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[DIV]]
173 ; CHECK-NEXT:    ret float [[R]]
175   %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
176   %neg = fsub float -0.000000e+00, %x
177   %div = fdiv float %neg, %y
178   call void @use(float %div)
179   %r = fadd float %z, %div
180   ret float %r
183 ; Z + (Y / -X) - extra use means we can't transform to fsub without an extra instruction
185 define float @fdiv_fneg2_extra_use(float %x, float %py, float %pz) {
186 ; CHECK-LABEL: @fdiv_fneg2_extra_use(
187 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
188 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
189 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
190 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y]], [[NEG]]
191 ; CHECK-NEXT:    call void @use(float [[DIV]])
192 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[DIV]]
193 ; CHECK-NEXT:    ret float [[R]]
195   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
196   %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
197   %neg = fsub float -0.000000e+00, %x
198   %div = fdiv float %y, %neg
199   call void @use(float %div)
200   %r = fadd float %z, %div
201   ret float %r
204 ; Z + (-X * Y) - extra use means we can't transform to fsub without an extra instruction
206 define <2 x float> @fmul_fneg1_extra_use(<2 x float> %x, <2 x float> %y, <2 x float> %pz) {
207 ; CHECK-LABEL: @fmul_fneg1_extra_use(
208 ; CHECK-NEXT:    [[Z:%.*]] = frem <2 x float> <float 4.200000e+01, float -1.000000e+00>, [[PZ:%.*]]
209 ; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
210 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
211 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
212 ; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[Z]], [[MUL]]
213 ; CHECK-NEXT:    ret <2 x float> [[R]]
215   %z = frem <2 x float> <float 42.0, float -1.0>, %pz ; thwart complexity-based canonicalization
216   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
217   %mul = fmul <2 x float> %neg, %y
218   call void @use_vec(<2 x float> %mul)
219   %r = fadd <2 x float> %z, %mul
220   ret <2 x float> %r
223 ; Z + (Y * -X) - extra use means we can't transform to fsub without an extra instruction
225 define float @fmul_fneg2_extra_use(float %x, float %py, float %pz) {
226 ; CHECK-LABEL: @fmul_fneg2_extra_use(
227 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
228 ; CHECK-NEXT:    [[Z:%.*]] = frem float 4.200000e+01, [[PZ:%.*]]
229 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
230 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
231 ; CHECK-NEXT:    call void @use(float [[MUL]])
232 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[Z]], [[MUL]]
233 ; CHECK-NEXT:    ret float [[R]]
235   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
236   %z = frem float 42.0, %pz ; thwart complexity-based canonicalization
237   %neg = fsub float -0.000000e+00, %x
238   %mul = fmul float %y, %neg
239   call void @use(float %mul)
240   %r = fadd float %z, %mul
241   ret float %r
244 ; (-X / Y) + Z --> Z - (X / Y)
246 define float @fdiv_fneg1_extra_use2(float %x, float %y, float %z) {
247 ; CHECK-LABEL: @fdiv_fneg1_extra_use2(
248 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
249 ; CHECK-NEXT:    call void @use(float [[NEG]])
250 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[X]], [[Y:%.*]]
251 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
252 ; CHECK-NEXT:    ret float [[R]]
254   %neg = fsub float -0.000000e+00, %x
255   call void @use(float %neg)
256   %div = fdiv float %neg, %y
257   %r = fadd float %div, %z
258   ret float %r
261 ; (Y / -X) + Z --> Z - (Y / X)
263 define float @fdiv_fneg2_extra_use2(float %x, float %y, float %z) {
264 ; CHECK-LABEL: @fdiv_fneg2_extra_use2(
265 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
266 ; CHECK-NEXT:    call void @use(float [[NEG]])
267 ; CHECK-NEXT:    [[TMP1:%.*]] = fdiv float [[Y:%.*]], [[X]]
268 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
269 ; CHECK-NEXT:    ret float [[R]]
271   %neg = fsub float -0.000000e+00, %x
272   call void @use(float %neg)
273   %div = fdiv float %y, %neg
274   %r = fadd float %div, %z
275   ret float %r
278 ; (-X * Y) + Z --> Z - (X * Y)
280 define <2 x float> @fmul_fneg1_extra_use2(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
281 ; CHECK-LABEL: @fmul_fneg1_extra_use2(
282 ; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
283 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
284 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul <2 x float> [[X]], [[Y:%.*]]
285 ; CHECK-NEXT:    [[R:%.*]] = fsub <2 x float> [[Z:%.*]], [[TMP1]]
286 ; CHECK-NEXT:    ret <2 x float> [[R]]
288   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
289   call void @use_vec(<2 x float> %neg)
290   %mul = fmul <2 x float> %neg, %y
291   %r = fadd <2 x float> %mul, %z
292   ret <2 x float> %r
295 ; (Y * -X) + Z --> Z - (Y * X)
297 define float @fmul_fneg2_extra_use2(float %x, float %py, float %z) {
298 ; CHECK-LABEL: @fmul_fneg2_extra_use2(
299 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
300 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
301 ; CHECK-NEXT:    call void @use(float [[NEG]])
302 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul float [[Y]], [[X]]
303 ; CHECK-NEXT:    [[R:%.*]] = fsub float [[Z:%.*]], [[TMP1]]
304 ; CHECK-NEXT:    ret float [[R]]
306   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
307   %neg = fsub float -0.000000e+00, %x
308   call void @use(float %neg)
309   %mul = fmul float %y, %neg
310   %r = fadd float %mul, %z
311   ret float %r
314 ; (-X / Y) + Z --> Z - (X / Y)
316 define float @fdiv_fneg1_extra_use3(float %x, float %y, float %z) {
317 ; CHECK-LABEL: @fdiv_fneg1_extra_use3(
318 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
319 ; CHECK-NEXT:    call void @use(float [[NEG]])
320 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[NEG]], [[Y:%.*]]
321 ; CHECK-NEXT:    call void @use(float [[DIV]])
322 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
323 ; CHECK-NEXT:    ret float [[R]]
325   %neg = fsub float -0.000000e+00, %x
326   call void @use(float %neg)
327   %div = fdiv float %neg, %y
328   call void @use(float %div)
329   %r = fadd float %div, %z
330   ret float %r
333 ; (Y / -X) + Z --> Z - (Y / X)
335 define float @fdiv_fneg2_extra_use3(float %x, float %y, float %z) {
336 ; CHECK-LABEL: @fdiv_fneg2_extra_use3(
337 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
338 ; CHECK-NEXT:    call void @use(float [[NEG]])
339 ; CHECK-NEXT:    [[DIV:%.*]] = fdiv float [[Y:%.*]], [[NEG]]
340 ; CHECK-NEXT:    call void @use(float [[DIV]])
341 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[DIV]], [[Z:%.*]]
342 ; CHECK-NEXT:    ret float [[R]]
344   %neg = fsub float -0.000000e+00, %x
345   call void @use(float %neg)
346   %div = fdiv float %y, %neg
347   call void @use(float %div)
348   %r = fadd float %div, %z
349   ret float %r
352 ; (-X * Y) + Z --> Z - (X * Y)
354 define <2 x float> @fmul_fneg1_extra_use3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
355 ; CHECK-LABEL: @fmul_fneg1_extra_use3(
356 ; CHECK-NEXT:    [[NEG:%.*]] = fneg <2 x float> [[X:%.*]]
357 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[NEG]])
358 ; CHECK-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[NEG]], [[Y:%.*]]
359 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[MUL]])
360 ; CHECK-NEXT:    [[R:%.*]] = fadd <2 x float> [[MUL]], [[Z:%.*]]
361 ; CHECK-NEXT:    ret <2 x float> [[R]]
363   %neg = fsub <2 x float> <float -0.0, float -0.0>, %x
364   call void @use_vec(<2 x float> %neg)
365   %mul = fmul <2 x float> %neg, %y
366   call void @use_vec(<2 x float> %mul)
367   %r = fadd <2 x float> %mul, %z
368   ret <2 x float> %r
371 ; (Y * -X) + Z --> Z - (Y * X)
373 define float @fmul_fneg2_extra_use3(float %x, float %py, float %z) {
374 ; CHECK-LABEL: @fmul_fneg2_extra_use3(
375 ; CHECK-NEXT:    [[Y:%.*]] = frem float -4.200000e+01, [[PY:%.*]]
376 ; CHECK-NEXT:    [[NEG:%.*]] = fneg float [[X:%.*]]
377 ; CHECK-NEXT:    call void @use(float [[NEG]])
378 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[Y]], [[NEG]]
379 ; CHECK-NEXT:    call void @use(float [[MUL]])
380 ; CHECK-NEXT:    [[R:%.*]] = fadd float [[MUL]], [[Z:%.*]]
381 ; CHECK-NEXT:    ret float [[R]]
383   %y = frem float -42.0, %py ; thwart complexity-based canonicalization
384   %neg = fsub float -0.000000e+00, %x
385   call void @use(float %neg)
386   %mul = fmul float %y, %neg
387   call void @use(float %mul)
388   %r = fadd float %mul, %z
389   ret float %r
392 define float @fadd_rdx(float %x, <4 x float> %v) {
393 ; CHECK-LABEL: @fadd_rdx(
394 ; CHECK-NEXT:    [[ADD:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[X:%.*]], <4 x float> [[V:%.*]])
395 ; CHECK-NEXT:    ret float [[ADD]]
397   %rdx = call fast float @llvm.vector.reduce.fadd.v4f32(float 0.0, <4 x float> %v)
398   %add = fadd fast float %rdx, %x
399   ret float %add
402 define float @fadd_rdx_commute(float %x, <4 x float> %v) {
403 ; CHECK-LABEL: @fadd_rdx_commute(
404 ; CHECK-NEXT:    [[D:%.*]] = fdiv float 4.200000e+01, [[X:%.*]]
405 ; CHECK-NEXT:    [[ADD:%.*]] = call reassoc nsz float @llvm.vector.reduce.fadd.v4f32(float [[D]], <4 x float> [[V:%.*]])
406 ; CHECK-NEXT:    ret float [[ADD]]
408   %d = fdiv float 42.0, %x
409   %rdx = call float @llvm.vector.reduce.fadd.v4f32(float -0.0, <4 x float> %v)
410   %add = fadd reassoc nsz float %d, %rdx
411   ret float %add
414 ; Negative test - require nsz to be safer (and reassoc obviously).
416 define float @fadd_rdx_fmf(float %x, <4 x float> %v) {
417 ; CHECK-LABEL: @fadd_rdx_fmf(
418 ; CHECK-NEXT:    [[RDX:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[V:%.*]])
419 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc float [[RDX]], [[X:%.*]]
420 ; CHECK-NEXT:    ret float [[ADD]]
422   %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 0.0, <4 x float> %v)
423   %add = fadd reassoc float %rdx, %x
424   ret float %add
427 ; Negative test - don't replace a single add with another reduction.
429 define float @fadd_rdx_extra_use(float %x, <4 x float> %v) {
430 ; CHECK-LABEL: @fadd_rdx_extra_use(
431 ; CHECK-NEXT:    [[RDX:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 0.000000e+00, <4 x float> [[V:%.*]])
432 ; CHECK-NEXT:    call void @use(float [[RDX]])
433 ; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[RDX]], [[X:%.*]]
434 ; CHECK-NEXT:    ret float [[ADD]]
436   %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 0.0, <4 x float> %v)
437   call void @use(float %rdx)
438   %add = fadd fast float %rdx, %x
439   ret float %add
442 define float @fadd_rdx_nonzero_start_const_op(<4 x float> %v) {
443 ; CHECK-LABEL: @fadd_rdx_nonzero_start_const_op(
444 ; CHECK-NEXT:    [[ADD:%.*]] = call reassoc ninf nsz float @llvm.vector.reduce.fadd.v4f32(float 3.300000e+01, <4 x float> [[V:%.*]])
445 ; CHECK-NEXT:    ret float [[ADD]]
447   %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 42.0, <4 x float> %v)
448   %add = fadd reassoc nsz ninf float %rdx, -9.0
449   ret float %add
452 ; Negative test - we don't change the order of ops unless it saves an instruction.
454 define float @fadd_rdx_nonzero_start_variable_op(float %x, <4 x float> %v) {
455 ; CHECK-LABEL: @fadd_rdx_nonzero_start_variable_op(
456 ; CHECK-NEXT:    [[RDX:%.*]] = call float @llvm.vector.reduce.fadd.v4f32(float 4.200000e+01, <4 x float> [[V:%.*]])
457 ; CHECK-NEXT:    [[ADD:%.*]] = fadd fast float [[RDX]], [[X:%.*]]
458 ; CHECK-NEXT:    ret float [[ADD]]
460   %rdx = call float @llvm.vector.reduce.fadd.v4f32(float 42.0, <4 x float> %v)
461   %add = fadd fast float %rdx, %x
462   ret float %add
465 ; (X * C) + X --> X * (C + 1)
467 define float @fadd_fmul_common_op(float %x) {
468 ; CHECK-LABEL: @fadd_fmul_common_op(
469 ; CHECK-NEXT:    [[A:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.300000e+01
470 ; CHECK-NEXT:    ret float [[A]]
472   %m = fmul reassoc nsz float %x, 42.0
473   %a = fadd reassoc nsz float %m, %x
474   ret float %a
477 ; Splat constant is ok.
479 define <2 x float> @fadd_fmul_common_op_vec(<2 x float> %x) {
480 ; CHECK-LABEL: @fadd_fmul_common_op_vec(
481 ; CHECK-NEXT:    [[A:%.*]] = fmul reassoc nsz <2 x float> [[X:%.*]], <float 4.300000e+01, float 4.300000e+01>
482 ; CHECK-NEXT:    ret <2 x float> [[A]]
484   %m = fmul reassoc nsz <2 x float> %x, <float 42.0, float 42.0>
485   %a = fadd reassoc nsz <2 x float> %m, %x
486   ret <2 x float> %a
489 ; Non-splat constant is ok.
491 define <2 x float> @fadd_fmul_common_op_commute_vec(<2 x float> %px) {
492 ; CHECK-LABEL: @fadd_fmul_common_op_commute_vec(
493 ; CHECK-NEXT:    [[X:%.*]] = fmul <2 x float> [[PX:%.*]], [[PX]]
494 ; CHECK-NEXT:    [[A:%.*]] = fmul reassoc nsz <2 x float> [[X]], <float 4.300000e+01, float -4.200000e+01>
495 ; CHECK-NEXT:    ret <2 x float> [[A]]
497   %x = fmul <2 x float> %px, %px ; thwart complexity-based canonicalization
498   %m = fmul reassoc nsz <2 x float> %x, <float 42.0, float -43.0>
499   %a = fadd reassoc nsz <2 x float> %x, %m
500   ret <2 x float> %a
503 ; Extra use is ok.
505 define float @fadd_fmul_common_op_use(float %x) {
506 ; CHECK-LABEL: @fadd_fmul_common_op_use(
507 ; CHECK-NEXT:    [[M:%.*]] = fmul reassoc nsz float [[X:%.*]], 4.200000e+01
508 ; CHECK-NEXT:    call void @use(float [[M]])
509 ; CHECK-NEXT:    [[A:%.*]] = fmul reassoc nsz float [[X]], 4.300000e+01
510 ; CHECK-NEXT:    ret float [[A]]
512   %m = fmul reassoc nsz float %x, 42.0
513   call void @use(float %m)
514   %a = fadd reassoc nsz float %m, %x
515   ret float %a
518 ; Negative test - must have 'reassoc' FMF
520 define float @fadd_fmul_common_op_wrong_fmf(float %x) {
521 ; CHECK-LABEL: @fadd_fmul_common_op_wrong_fmf(
522 ; CHECK-NEXT:    [[M:%.*]] = fmul ninf nsz float [[X:%.*]], 4.200000e+01
523 ; CHECK-NEXT:    [[A:%.*]] = fadd ninf nsz float [[M]], [[X]]
524 ; CHECK-NEXT:    ret float [[A]]
526   %m = fmul ninf nsz float %x, 42.0
527   %a = fadd ninf nsz float %m, %x
528   ret float %a
531 ; (-x - y) + (x + z) --> z - y
533 define float @fadd_fneg_reass_commute0(float %x, float %y, float %z) {
534 ; CHECK-LABEL: @fadd_fneg_reass_commute0(
535 ; CHECK-NEXT:    [[N:%.*]] = fneg reassoc nsz float [[X:%.*]]
536 ; CHECK-NEXT:    call void @use(float [[N]])
537 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[Y:%.*]]
538 ; CHECK-NEXT:    ret float [[R]]
540   %n = fneg reassoc nsz float %x
541   call void @use(float %n)
542   %s = fsub reassoc nsz float %n, %y
543   %a = fadd reassoc nsz float %x, %z
544   %r = fadd reassoc nsz float %s, %a
545   ret float %r
548 define float @fadd_fneg_reass_commute1(float %x, float %y, float %z) {
549 ; CHECK-LABEL: @fadd_fneg_reass_commute1(
550 ; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
551 ; CHECK-NEXT:    call void @use(float [[N]])
552 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[N]], [[Y:%.*]]
553 ; CHECK-NEXT:    call void @use(float [[S]])
554 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz float [[Z:%.*]], [[Y]]
555 ; CHECK-NEXT:    ret float [[R]]
557   %n = fneg float %x
558   call void @use(float %n)
559   %s = fsub float %n, %y
560   call void @use(float %s)
561   %a = fadd float %x, %z
562   %r = fadd reassoc nsz float %a, %s
563   ret float %r
566 define float @fadd_fneg_reass_commute2(float %x, float %y, float %z) {
567 ; CHECK-LABEL: @fadd_fneg_reass_commute2(
568 ; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
569 ; CHECK-NEXT:    call void @use(float [[N]])
570 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[N]], [[Y:%.*]]
571 ; CHECK-NEXT:    call void @use(float [[S]])
572 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[Z:%.*]], [[X]]
573 ; CHECK-NEXT:    call void @use(float [[A]])
574 ; CHECK-NEXT:    [[R:%.*]] = fsub fast float [[Z]], [[Y]]
575 ; CHECK-NEXT:    ret float [[R]]
577   %n = fneg float %x
578   call void @use(float %n)
579   %s = fsub float %n, %y
580   call void @use(float %s)
581   %a = fadd float %z, %x
582   call void @use(float %a)
583   %r = fadd fast float %s, %a
584   ret float %r
587 define <2 x float> @fadd_fneg_reass_commute3(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
588 ; CHECK-LABEL: @fadd_fneg_reass_commute3(
589 ; CHECK-NEXT:    [[N:%.*]] = fneg reassoc nsz <2 x float> [[X:%.*]]
590 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[N]])
591 ; CHECK-NEXT:    [[R:%.*]] = fsub reassoc nsz <2 x float> [[Z:%.*]], [[Y:%.*]]
592 ; CHECK-NEXT:    ret <2 x float> [[R]]
594   %n = fneg reassoc nsz <2 x float> %x
595   call void @use_vec(<2 x float> %n)
596   %s = fsub reassoc nsz <2 x float> %n, %y
597   %a = fadd reassoc nsz <2 x float> %z, %x
598   %r = fadd reassoc nsz <2 x float> %a, %s
599   ret <2 x float> %r
602 ; negative test - need reassoc (+ nsz)
604 define float @fadd_fneg_commute0(float %x, float %y, float %z) {
605 ; CHECK-LABEL: @fadd_fneg_commute0(
606 ; CHECK-NEXT:    [[N:%.*]] = fneg float [[X:%.*]]
607 ; CHECK-NEXT:    call void @use(float [[N]])
608 ; CHECK-NEXT:    [[S:%.*]] = fsub float [[N]], [[Y:%.*]]
609 ; CHECK-NEXT:    [[A:%.*]] = fadd float [[X]], [[Z:%.*]]
610 ; CHECK-NEXT:    [[R:%.*]] = fadd nsz float [[S]], [[A]]
611 ; CHECK-NEXT:    ret float [[R]]
613   %n = fneg float %x
614   call void @use(float %n)
615   %s = fsub float %n, %y
616   %a = fadd float %x, %z
617   %r = fadd nsz float %s, %a
618   ret float %r
621 define float @fadd_reduce_sqr_sum_varA(float %a, float %b) {
622 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA(
623 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
624 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
625 ; CHECK-NEXT:    ret float [[ADD]]
627   %a_sq = fmul float %a, %a
628   %two_a = fmul float %a, 2.0
629   %two_a_plus_b = fadd float %two_a, %b
630   %mul = fmul float %two_a_plus_b, %b
631   %add = fadd reassoc nsz float %mul, %a_sq
632   ret float %add
635 define float @fadd_reduce_sqr_sum_varA_order2(float %a, float %b) {
636 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order2(
637 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
638 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
639 ; CHECK-NEXT:    ret float [[ADD]]
641   %a_sq = fmul float %a, %a
642   %two_a = fmul float %a, 2.0
643   %two_a_plus_b = fadd float %two_a, %b
644   %mul = fmul float %two_a_plus_b, %b
645   %add = fadd reassoc nsz float %a_sq, %mul
646   ret float %add
649 define float @fadd_reduce_sqr_sum_varA_order3(float %a, float %b) {
650 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order3(
651 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
652 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
653 ; CHECK-NEXT:    ret float [[ADD]]
655   %a_sq = fmul float %a, %a
656   %two_a = fmul float %a, 2.0
657   %two_a_plus_b = fadd float %two_a, %b
658   %mul = fmul float %b, %two_a_plus_b
659   %add = fadd reassoc nsz float %mul, %a_sq
660   ret float %add
663 define float @fadd_reduce_sqr_sum_varA_order4(float %a, float %b) {
664 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order4(
665 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
666 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
667 ; CHECK-NEXT:    ret float [[ADD]]
669   %a_sq = fmul float %a, %a
670   %two_a = fmul float %a, 2.0
671   %two_a_plus_b = fadd float %b, %two_a
672   %mul = fmul float %two_a_plus_b, %b
673   %add = fadd reassoc nsz float %mul, %a_sq
674   ret float %add
677 define float @fadd_reduce_sqr_sum_varA_order5(float %a, float %b) {
678 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_order5(
679 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
680 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
681 ; CHECK-NEXT:    ret float [[ADD]]
683   %a_sq = fmul float %a, %a
684   %two_a = fmul float 2.0, %a
685   %two_a_plus_b = fadd float %two_a, %b
686   %mul = fmul float %two_a_plus_b, %b
687   %add = fadd reassoc nsz float %mul, %a_sq
688   ret float %add
691 define float @fadd_reduce_sqr_sum_varB(float %a, float %b) {
692 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB(
693 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
694 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
695 ; CHECK-NEXT:    ret float [[ADD]]
697   %a_b = fmul float %a, %b
698   %a_b_2 = fmul float %a_b, 2.0
699   %a_sq = fmul float %a, %a
700   %b_sq = fmul float %b, %b
701   %a_sq_b_sq = fadd float %a_sq, %b_sq
702   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
703   ret float %add
706 define float @fadd_reduce_sqr_sum_varB_order1(float %a, float %b) {
707 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_order1(
708 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
709 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
710 ; CHECK-NEXT:    ret float [[ADD]]
712   %a_b = fmul float %a, %b
713   %a_b_2 = fmul float %a_b, 2.0
714   %a_sq = fmul float %a, %a
715   %b_sq = fmul float %b, %b
716   %a_sq_b_sq = fadd float %a_sq, %b_sq
717   %add = fadd reassoc nsz float %a_sq_b_sq, %a_b_2
718   ret float %add
721 define float @fadd_reduce_sqr_sum_varB_order2(float %a, float %b) {
722 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_order2(
723 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
724 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
725 ; CHECK-NEXT:    ret float [[ADD]]
727   %a_b = fmul float %a, %b
728   %a_b_2 = fmul float %a_b, 2.0
729   %a_sq = fmul float %a, %a
730   %b_sq = fmul float %b, %b
731   %a_sq_b_sq = fadd float %b_sq, %a_sq
732   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
733   ret float %add
736 define float @fadd_reduce_sqr_sum_varB_order3(float %a, float %b) {
737 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_order3(
738 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[B:%.*]], [[A:%.*]]
739 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
740 ; CHECK-NEXT:    ret float [[ADD]]
742   %a_b = fmul float %b, %a
743   %a_b_2 = fmul float 2.0, %a_b
744   %a_sq = fmul float %a, %a
745   %b_sq = fmul float %b, %b
746   %a_sq_b_sq = fadd float %a_sq, %b_sq
747   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
748   ret float %add
751 define float @fadd_reduce_sqr_sum_varB2(float %a, float %b) {
752 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2(
753 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
754 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
755 ; CHECK-NEXT:    ret float [[ADD]]
757   %a_2 = fmul float %a, 2.0
758   %a_b_2 = fmul float %a_2, %b
759   %a_sq = fmul float %a, %a
760   %b_sq = fmul float %b, %b
761   %a_sq_b_sq = fadd float %a_sq, %b_sq
762   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
763   ret float %add
766 define float @fadd_reduce_sqr_sum_varB2_order1(float %a, float %b) {
767 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_order1(
768 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
769 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
770 ; CHECK-NEXT:    ret float [[ADD]]
772   %a_2 = fmul float %a, 2.0
773   %a_b_2 = fmul float %a_2, %b
774   %a_sq = fmul float %a, %a
775   %b_sq = fmul float %b, %b
776   %a_sq_b_sq = fadd float %a_sq, %b_sq
777   %add = fadd reassoc nsz float %a_sq_b_sq, %a_b_2
778   ret float %add
781 define float @fadd_reduce_sqr_sum_varB2_order2(float %a, float %b) {
782 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_order2(
783 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
784 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
785 ; CHECK-NEXT:    ret float [[ADD]]
787   %a_2 = fmul float %a, 2.0
788   %a_b_2 = fmul float %b, %a_2
789   %a_sq = fmul float %a, %a
790   %b_sq = fmul float %b, %b
791   %a_sq_b_sq = fadd float %a_sq, %b_sq
792   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
793   ret float %add
796 define float @fadd_reduce_sqr_sum_varB2_order3(float %a, float %b) {
797 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_order3(
798 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[A:%.*]], [[B:%.*]]
799 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[TMP1]]
800 ; CHECK-NEXT:    ret float [[ADD]]
802   %a_2 = fmul float 2.0, %a
803   %a_b_2 = fmul float %a_2, %b
804   %a_sq = fmul float %a, %a
805   %b_sq = fmul float %b, %b
806   %a_sq_b_sq = fadd float %a_sq, %b_sq
807   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
808   ret float %add
811 define float @fadd_reduce_sqr_sum_varA_not_one_use1(float %a, float %b) {
812 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_not_one_use1(
813 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
814 ; CHECK-NEXT:    [[TWO_A:%.*]] = fmul float [[A]], 2.000000e+00
815 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]
816 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]
817 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]
818 ; CHECK-NEXT:    tail call void @fake_func(float [[MUL]])
819 ; CHECK-NEXT:    ret float [[ADD]]
821   %a_sq = fmul float %a, %a
822   %two_a = fmul float %a, 2.0
823   %two_a_plus_b = fadd float %two_a, %b
824   %mul = fmul float %two_a_plus_b, %b
825   %add = fadd reassoc nsz float %mul, %a_sq
826   tail call void @fake_func (float %mul)
827   ret float %add
830 define float @fadd_reduce_sqr_sum_varA_not_one_use2(float %a, float %b) {
831 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_not_one_use2(
832 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
833 ; CHECK-NEXT:    [[TWO_A:%.*]] = fmul float [[A]], 2.000000e+00
834 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]
835 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]
836 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]
837 ; CHECK-NEXT:    tail call void @fake_func(float [[A_SQ]])
838 ; CHECK-NEXT:    ret float [[ADD]]
840   %a_sq = fmul float %a, %a
841   %two_a = fmul float %a, 2.0
842   %two_a_plus_b = fadd float %two_a, %b
843   %mul = fmul float %two_a_plus_b, %b
844   %add = fadd reassoc nsz float %mul, %a_sq
845   tail call void @fake_func (float %a_sq)
846   ret float %add
849 define float @fadd_reduce_sqr_sum_varB_not_one_use1(float %a, float %b) {
850 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_not_one_use1(
851 ; CHECK-NEXT:    [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]
852 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+00
853 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
854 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
855 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
856 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
857 ; CHECK-NEXT:    tail call void @fake_func(float [[A_B_2]])
858 ; CHECK-NEXT:    ret float [[ADD]]
860   %a_b = fmul float %a, %b
861   %a_b_2 = fmul float %a_b, 2.0
862   %a_sq = fmul float %a, %a
863   %b_sq = fmul float %b, %b
864   %a_sq_b_sq = fadd float %a_sq, %b_sq
865   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
866   tail call void @fake_func (float %a_b_2)
867   ret float %add
870 define float @fadd_reduce_sqr_sum_varB_not_one_use2(float %a, float %b) {
871 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_not_one_use2(
872 ; CHECK-NEXT:    [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]
873 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+00
874 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
875 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
876 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
877 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
878 ; CHECK-NEXT:    tail call void @fake_func(float [[A_SQ_B_SQ]])
879 ; CHECK-NEXT:    ret float [[ADD]]
881   %a_b = fmul float %a, %b
882   %a_b_2 = fmul float %a_b, 2.0
883   %a_sq = fmul float %a, %a
884   %b_sq = fmul float %b, %b
885   %a_sq_b_sq = fadd float %a_sq, %b_sq
886   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
887   tail call void @fake_func (float %a_sq_b_sq)
888   ret float %add
891 define float @fadd_reduce_sqr_sum_varB2_not_one_use(float %a, float %b) {
892 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_not_one_use(
893 ; CHECK-NEXT:    [[A_2:%.*]] = fmul float [[A:%.*]], 2.000000e+00
894 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[A_2]], [[B:%.*]]
895 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
896 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
897 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
898 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
899 ; CHECK-NEXT:    tail call void @fake_func(float [[A_B_2]])
900 ; CHECK-NEXT:    ret float [[ADD]]
902   %a_2 = fmul float %a, 2.0
903   %a_b_2 = fmul float %a_2, %b
904   %a_sq = fmul float %a, %a
905   %b_sq = fmul float %b, %b
906   %a_sq_b_sq = fadd float %a_sq, %b_sq
907   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
908   tail call void @fake_func (float %a_b_2)
909   ret float %add
912 define float @fadd_reduce_sqr_sum_varA_invalid1(float %a, float %b) {
913 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid1(
914 ; CHECK-NEXT:    [[TWO_A:%.*]] = fmul float [[A:%.*]], 2.000000e+00
915 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]
916 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[TWO_A_PLUS_B]], [[A]]
917 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[A]]
918 ; CHECK-NEXT:    ret float [[ADD]]
920   %a_sq = fmul float %a, %a
921   %two_a = fmul float %a, 2.0
922   %two_a_plus_b = fadd float %two_a, %b
923   %mul = fmul float %two_a_plus_b, %a
924   %add = fadd reassoc nsz float %mul, %a_sq
925   ret float %add
928 define float @fadd_reduce_sqr_sum_varA_invalid2(float %a, float %b) {
929 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid2(
930 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
931 ; CHECK-NEXT:    [[TWO_A:%.*]] = fmul float [[A]], 2.000000e+00
932 ; CHECK-NEXT:    [[NOT_TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[A]]
933 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[NOT_TWO_A_PLUS_B]], [[B:%.*]]
934 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]
935 ; CHECK-NEXT:    ret float [[ADD]]
937   %a_sq = fmul float %a, %a
938   %two_a = fmul float %a, 2.0
939   %not_two_a_plus_b = fadd float %two_a, %a
940   %mul = fmul float %not_two_a_plus_b, %b
941   %add = fadd reassoc nsz float %mul, %a_sq
942   ret float %add
945 define float @fadd_reduce_sqr_sum_varA_invalid3(float %a, float %b) {
946 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid3(
947 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
948 ; CHECK-NEXT:    [[NOT_TWO_A:%.*]] = fmul float [[A]], 0x4000CCCCC0000000
949 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = fadd float [[NOT_TWO_A]], [[B:%.*]]
950 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]
951 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]
952 ; CHECK-NEXT:    ret float [[ADD]]
954   %a_sq = fmul float %a, %a
955   %not_two_a = fmul float %a, 0x4000CCCCC0000000 ; 2.1
956   %two_a_plus_b = fadd float %not_two_a, %b
957   %mul = fmul float %two_a_plus_b, %b
958   %add = fadd reassoc nsz float %mul, %a_sq
959   ret float %add
962 define float @fadd_reduce_sqr_sum_varA_invalid4(float %a, float %b) {
963 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid4(
964 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
965 ; CHECK-NEXT:    [[NOT_TWO_A:%.*]] = fmul float [[B:%.*]], 2.000000e+00
966 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = fadd float [[NOT_TWO_A]], [[B]]
967 ; CHECK-NEXT:    [[MUL:%.*]] = fmul float [[TWO_A_PLUS_B]], [[B]]
968 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[MUL]], [[A_SQ]]
969 ; CHECK-NEXT:    ret float [[ADD]]
971   %a_sq = fmul float %a, %a
972   %not_two_a = fmul float %b, 2.0
973   %two_a_plus_b = fadd float %not_two_a, %b
974   %mul = fmul float %two_a_plus_b, %b
975   %add = fadd reassoc nsz float %mul, %a_sq
976   ret float %add
979 define float @fadd_reduce_sqr_sum_varA_invalid5(float %a, float %b) {
980 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varA_invalid5(
981 ; CHECK-NEXT:    [[TWO_A:%.*]] = fmul float [[A:%.*]], 2.000000e+00
982 ; CHECK-NEXT:    [[TWO_A_PLUS_B:%.*]] = fadd float [[TWO_A]], [[B:%.*]]
983 ; CHECK-NEXT:    [[TMP1:%.*]] = fadd reassoc nsz float [[TWO_A_PLUS_B]], [[A]]
984 ; CHECK-NEXT:    [[ADD:%.*]] = fmul reassoc nsz float [[TMP1]], [[B]]
985 ; CHECK-NEXT:    ret float [[ADD]]
987   %not_a_sq = fmul float %a, %b
988   %two_a = fmul float %a, 2.0
989   %two_a_plus_b = fadd float %two_a, %b
990   %mul = fmul float %two_a_plus_b, %b
991   %add = fadd reassoc nsz float %mul, %not_a_sq
992   ret float %add
995 define float @fadd_reduce_sqr_sum_varB_invalid1(float %a, float %b) {
996 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid1(
997 ; CHECK-NEXT:    [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]
998 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+00
999 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
1000 ; CHECK-NEXT:    [[NOT_B_SQ:%.*]] = fmul float [[B]], [[A]]
1001 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[NOT_B_SQ]]
1002 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
1003 ; CHECK-NEXT:    ret float [[ADD]]
1005   %a_b = fmul float %a, %b
1006   %a_b_2 = fmul float %a_b, 2.0
1007   %a_sq = fmul float %a, %a
1008   %not_b_sq = fmul float %b, %a
1009   %a_sq_b_sq = fadd float %a_sq, %not_b_sq
1010   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
1011   ret float %add
1014 define float @fadd_reduce_sqr_sum_varB_invalid2(float %a, float %b) {
1015 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid2(
1016 ; CHECK-NEXT:    [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]
1017 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[A_B]], 2.000000e+00
1018 ; CHECK-NEXT:    [[NOT_A_SQ:%.*]] = fmul float [[A]], [[B]]
1019 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
1020 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[NOT_A_SQ]], [[B_SQ]]
1021 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
1022 ; CHECK-NEXT:    ret float [[ADD]]
1024   %a_b = fmul float %a, %b
1025   %a_b_2 = fmul float %a_b, 2.0
1026   %not_a_sq = fmul float %a, %b
1027   %b_sq = fmul float %b, %b
1028   %a_sq_b_sq = fadd float %not_a_sq, %b_sq
1029   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
1030   ret float %add
1033 define float @fadd_reduce_sqr_sum_varB_invalid3(float %a, float %b) {
1034 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid3(
1035 ; CHECK-NEXT:    [[A_B:%.*]] = fmul float [[A:%.*]], [[B:%.*]]
1036 ; CHECK-NEXT:    [[NOT_A_B_2:%.*]] = fmul float [[A_B]], 0x4000CCCCC0000000
1037 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
1038 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
1039 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
1040 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[NOT_A_B_2]], [[A_SQ_B_SQ]]
1041 ; CHECK-NEXT:    ret float [[ADD]]
1043   %a_b = fmul float %a, %b
1044   %not_a_b_2 = fmul float %a_b, 0x4000CCCCC0000000 ; 2.1
1045   %a_sq = fmul float %a, %a
1046   %b_sq = fmul float %b, %b
1047   %a_sq_b_sq = fadd float %a_sq, %b_sq
1048   %add = fadd reassoc nsz float %not_a_b_2, %a_sq_b_sq
1049   ret float %add
1052 define float @fadd_reduce_sqr_sum_varB_invalid4(float %a, float %b) {
1053 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid4(
1054 ; CHECK-NEXT:    [[NOT_A_B:%.*]] = fmul float [[A:%.*]], [[A]]
1055 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[NOT_A_B]], 2.000000e+00
1056 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
1057 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B:%.*]], [[B]]
1058 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
1059 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
1060 ; CHECK-NEXT:    ret float [[ADD]]
1062   %not_a_b = fmul float %a, %a
1063   %a_b_2 = fmul float %not_a_b, 2.0
1064   %a_sq = fmul float %a, %a
1065   %b_sq = fmul float %b, %b
1066   %a_sq_b_sq = fadd float %a_sq, %b_sq
1067   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
1068   ret float %add
1071 define float @fadd_reduce_sqr_sum_varB_invalid5(float %a, float %b) {
1072 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB_invalid5(
1073 ; CHECK-NEXT:    [[NOT_A_B:%.*]] = fmul float [[B:%.*]], [[B]]
1074 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[NOT_A_B]], 2.000000e+00
1075 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
1076 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
1077 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
1078 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
1079 ; CHECK-NEXT:    ret float [[ADD]]
1081   %not_a_b = fmul float %b, %b
1082   %a_b_2 = fmul float %not_a_b, 2.0
1083   %a_sq = fmul float %a, %a
1084   %b_sq = fmul float %b, %b
1085   %a_sq_b_sq = fadd float %a_sq, %b_sq
1086   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
1087   ret float %add
1090 define float @fadd_reduce_sqr_sum_varB2_invalid1(float %a, float %b) {
1091 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_invalid1(
1092 ; CHECK-NEXT:    [[A_2:%.*]] = fmul float [[A:%.*]], 2.000000e+00
1093 ; CHECK-NEXT:    [[NOT_A_B_2:%.*]] = fmul float [[A_2]], [[A]]
1094 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
1095 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B:%.*]], [[B]]
1096 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
1097 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[NOT_A_B_2]], [[A_SQ_B_SQ]]
1098 ; CHECK-NEXT:    ret float [[ADD]]
1100   %a_2 = fmul float %a, 2.0
1101   %not_a_b_2 = fmul float %a_2, %a
1102   %a_sq = fmul float %a, %a
1103   %b_sq = fmul float %b, %b
1104   %a_sq_b_sq = fadd float %a_sq, %b_sq
1105   %add = fadd reassoc nsz float %not_a_b_2, %a_sq_b_sq
1106   ret float %add
1109 define float @fadd_reduce_sqr_sum_varB2_invalid2(float %a, float %b) {
1110 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_invalid2(
1111 ; CHECK-NEXT:    [[NOT_A_2:%.*]] = fmul float [[A:%.*]], 0x4000CCCCC0000000
1112 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[NOT_A_2]], [[B:%.*]]
1113 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A]], [[A]]
1114 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
1115 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
1116 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
1117 ; CHECK-NEXT:    ret float [[ADD]]
1119   %not_a_2 = fmul float %a, 0x4000CCCCC0000000 ; 2.1
1120   %a_b_2 = fmul float %not_a_2, %b
1121   %a_sq = fmul float %a, %a
1122   %b_sq = fmul float %b, %b
1123   %a_sq_b_sq = fadd float %a_sq, %b_sq
1124   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
1125   ret float %add
1128 define float @fadd_reduce_sqr_sum_varB2_invalid3(float %a, float %b) {
1129 ; CHECK-LABEL: @fadd_reduce_sqr_sum_varB2_invalid3(
1130 ; CHECK-NEXT:    [[NOT_A_2:%.*]] = fmul float [[B:%.*]], 2.000000e+00
1131 ; CHECK-NEXT:    [[A_B_2:%.*]] = fmul float [[NOT_A_2]], [[B]]
1132 ; CHECK-NEXT:    [[A_SQ:%.*]] = fmul float [[A:%.*]], [[A]]
1133 ; CHECK-NEXT:    [[B_SQ:%.*]] = fmul float [[B]], [[B]]
1134 ; CHECK-NEXT:    [[A_SQ_B_SQ:%.*]] = fadd float [[A_SQ]], [[B_SQ]]
1135 ; CHECK-NEXT:    [[ADD:%.*]] = fadd reassoc nsz float [[A_B_2]], [[A_SQ_B_SQ]]
1136 ; CHECK-NEXT:    ret float [[ADD]]
1138   %not_a_2 = fmul float %b, 2.0
1139   %a_b_2 = fmul float %not_a_2, %b
1140   %a_sq = fmul float %a, %a
1141   %b_sq = fmul float %b, %b
1142   %a_sq_b_sq = fadd float %a_sq, %b_sq
1143   %add = fadd reassoc nsz float %a_b_2, %a_sq_b_sq
1144   ret float %add
1147 declare void @fake_func(float)