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>)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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]]
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
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]]
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
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
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]]
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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)
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
1147 declare void @fake_func(float)