[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / test / Transforms / InstCombine / fadd.ll
blob8191375fda448c2b7175575f56936d20d6a9a9d2
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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:    [[TMP1:%.*]] = call fast float @llvm.vector.reduce.fadd.v4f32(float [[X:%.*]], <4 x float> [[V:%.*]])
395 ; CHECK-NEXT:    ret float [[TMP1]]
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:    [[TMP1:%.*]] = call reassoc nsz float @llvm.vector.reduce.fadd.v4f32(float [[D]], <4 x float> [[V:%.*]])
406 ; CHECK-NEXT:    ret float [[TMP1]]
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:    [[TMP1:%.*]] = call reassoc ninf nsz float @llvm.vector.reduce.fadd.v4f32(float 3.300000e+01, <4 x float> [[V:%.*]])
445 ; CHECK-NEXT:    ret float [[TMP1]]
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