Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / InstCombine / fma.ll
blob8b413ae6f664b0a24761e03c6e609a8276e48dfb
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=instcombine < %s | FileCheck %s
4 declare float @llvm.fma.f32(float, float, float)
5 declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>)
6 declare <3 x float> @llvm.fma.v3f32(<3 x float>, <3 x float>, <3 x float>)
7 declare <8 x half> @llvm.fma.v8f16(<8 x half>, <8 x half>, <8 x half>)
8 declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>)
10 declare float @llvm.fmuladd.f32(float, float, float)
11 declare <2 x double> @llvm.fmuladd.v2f64(<2 x double>, <2 x double>, <2 x double>)
12 declare float @llvm.fabs.f32(float)
13 declare <2 x double> @llvm.sqrt.v2f64(<2 x double>)
14 declare void @use_vec(<2 x float>)
15 declare void @use_vec3(<3 x float>)
17 @external = external global i32
19 define float @fma_fneg_x_fneg_y(float %x, float %y, float %z) {
20 ; CHECK-LABEL: @fma_fneg_x_fneg_y(
21 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
22 ; CHECK-NEXT:    ret float [[FMA]]
24   %x.fneg = fsub float -0.0, %x
25   %y.fneg = fsub float -0.0, %y
26   %fma = call float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)
27   ret float %fma
30 define float @fma_unary_fneg_x_unary_fneg_y(float %x, float %y, float %z) {
31 ; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_y(
32 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
33 ; CHECK-NEXT:    ret float [[FMA]]
35   %x.fneg = fneg float %x
36   %y.fneg = fneg float %y
37   %fma = call float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)
38   ret float %fma
41 define <2 x float> @fma_fneg_x_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
42 ; CHECK-LABEL: @fma_fneg_x_fneg_y_vec(
43 ; CHECK-NEXT:    [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
44 ; CHECK-NEXT:    ret <2 x float> [[FMA]]
46   %xn = fsub <2 x float> <float -0.0, float -0.0>, %x
47   %yn = fsub <2 x float> <float -0.0, float -0.0>, %y
48   %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
49   ret <2 x float> %fma
52 define <2 x float> @fma_unary_fneg_x_unary_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
53 ; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_y_vec(
54 ; CHECK-NEXT:    [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
55 ; CHECK-NEXT:    ret <2 x float> [[FMA]]
57   %xn = fneg <2 x float> %x
58   %yn = fneg <2 x float> %y
59   %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
60   ret <2 x float> %fma
63 define <2 x float> @fma_fneg_x_fneg_y_vec_undef(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
64 ; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_undef(
65 ; CHECK-NEXT:    [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
66 ; CHECK-NEXT:    ret <2 x float> [[FMA]]
68   %xn = fsub <2 x float> <float -0.0, float undef>, %x
69   %yn = fsub <2 x float> <float undef, float -0.0>, %y
70   %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
71   ret <2 x float> %fma
74 define float @fma_fneg_x_fneg_y_fast(float %x, float %y, float %z) {
75 ; CHECK-LABEL: @fma_fneg_x_fneg_y_fast(
76 ; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
77 ; CHECK-NEXT:    ret float [[FMA]]
79   %x.fneg = fsub float -0.0, %x
80   %y.fneg = fsub float -0.0, %y
81   %fma = call fast float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)
82   ret float %fma
85 define float @fma_unary_fneg_x_unary_fneg_y_fast(float %x, float %y, float %z) {
86 ; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_y_fast(
87 ; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
88 ; CHECK-NEXT:    ret float [[FMA]]
90   %x.fneg = fneg float %x
91   %y.fneg = fneg float %y
92   %fma = call fast float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)
93   ret float %fma
96 define float @fma_fneg_const_fneg_y(float %y, float %z) {
97 ; CHECK-LABEL: @fma_fneg_const_fneg_y(
98 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
99 ; CHECK-NEXT:    ret float [[FMA]]
101   %y.fneg = fsub float -0.0, %y
102   %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)
103   %fma = call float @llvm.fma.f32(float %fsub, float %y.fneg, float %z)
104   ret float %fma
107 define float @fma_unary_fneg_const_unary_fneg_y(float %y, float %z) {
108 ; CHECK-LABEL: @fma_unary_fneg_const_unary_fneg_y(
109 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
110 ; CHECK-NEXT:    ret float [[FMA]]
112   %y.fneg = fneg float %y
113   %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)
114   %fma = call float @llvm.fma.f32(float %external.fneg, float %y.fneg, float %z)
115   ret float %fma
118 define float @fma_fneg_x_fneg_const(float %x, float %z) {
119 ; CHECK-LABEL: @fma_fneg_x_fneg_const(
120 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
121 ; CHECK-NEXT:    ret float [[FMA]]
123   %x.fneg = fsub float -0.0, %x
124   %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)
125   %fma = call float @llvm.fma.f32(float %x.fneg, float %fsub, float %z)
126   ret float %fma
129 define float @fma_unary_fneg_x_unary_fneg_const(float %x, float %z) {
130 ; CHECK-LABEL: @fma_unary_fneg_x_unary_fneg_const(
131 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
132 ; CHECK-NEXT:    ret float [[FMA]]
134   %x.fneg = fneg float %x
135   %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)
136   %fma = call float @llvm.fma.f32(float %x.fneg, float %external.fneg, float %z)
137   ret float %fma
140 define float @fma_fabs_x_fabs_y(float %x, float %y, float %z) {
141 ; CHECK-LABEL: @fma_fabs_x_fabs_y(
142 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
143 ; CHECK-NEXT:    [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])
144 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]])
145 ; CHECK-NEXT:    ret float [[FMA]]
147   %x.fabs = call float @llvm.fabs.f32(float %x)
148   %y.fabs = call float @llvm.fabs.f32(float %y)
149   %fma = call float @llvm.fma.f32(float %x.fabs, float %y.fabs, float %z)
150   ret float %fma
153 define float @fma_fabs_x_fabs_x(float %x, float %z) {
154 ; CHECK-LABEL: @fma_fabs_x_fabs_x(
155 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])
156 ; CHECK-NEXT:    ret float [[FMA]]
158   %x.fabs = call float @llvm.fabs.f32(float %x)
159   %fma = call float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z)
160   ret float %fma
163 define float @fma_fabs_x_fabs_x_fast(float %x, float %z) {
164 ; CHECK-LABEL: @fma_fabs_x_fabs_x_fast(
165 ; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])
166 ; CHECK-NEXT:    ret float [[FMA]]
168   %x.fabs = call float @llvm.fabs.f32(float %x)
169   %fma = call fast float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z)
170   ret float %fma
173 define float @fmuladd_fneg_x_fneg_y(float %x, float %y, float %z) {
174 ; CHECK-LABEL: @fmuladd_fneg_x_fneg_y(
175 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
176 ; CHECK-NEXT:    ret float [[FMULADD]]
178   %x.fneg = fsub float -0.0, %x
179   %y.fneg = fsub float -0.0, %y
180   %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)
181   ret float %fmuladd
184 define float @fmuladd_unary_fneg_x_unary_fneg_y(float %x, float %y, float %z) {
185 ; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_y(
186 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
187 ; CHECK-NEXT:    ret float [[FMULADD]]
189   %x.fneg = fneg float %x
190   %y.fneg = fneg float %y
191   %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)
192   ret float %fmuladd
195 define float @fmuladd_fneg_x_fneg_y_fast(float %x, float %y, float %z) {
196 ; CHECK-LABEL: @fmuladd_fneg_x_fneg_y_fast(
197 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[Y:%.*]]
198 ; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
199 ; CHECK-NEXT:    ret float [[FMULADD]]
201   %x.fneg = fsub float -0.0, %x
202   %y.fneg = fsub float -0.0, %y
203   %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)
204   ret float %fmuladd
207 define float @fmuladd_unary_fneg_x_unary_fneg_y_fast(float %x, float %y, float %z) {
208 ; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_y_fast(
209 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[Y:%.*]]
210 ; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
211 ; CHECK-NEXT:    ret float [[FMULADD]]
213   %x.fneg = fneg float %x
214   %y.fneg = fneg float %y
215   %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)
216   ret float %fmuladd
219 define float @fmuladd_fneg_const_fneg_y(float %y, float %z) {
220 ; CHECK-LABEL: @fmuladd_fneg_const_fneg_y(
221 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
222 ; CHECK-NEXT:    ret float [[FMULADD]]
224   %y.fneg = fsub float -0.0, %y
225   %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)
226   %fmuladd = call float @llvm.fmuladd.f32(float %fsub, float %y.fneg, float %z)
227   ret float %fmuladd
230 define float @fmuladd_unary_fneg_const_unary_fneg_y(float %y, float %z) {
231 ; CHECK-LABEL: @fmuladd_unary_fneg_const_unary_fneg_y(
232 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
233 ; CHECK-NEXT:    ret float [[FMULADD]]
235   %y.fneg = fneg float %y
236   %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)
237   %fmuladd = call float @llvm.fmuladd.f32(float %external.fneg, float %y.fneg, float %z)
238   ret float %fmuladd
241 define float @fmuladd_fneg_x_fneg_const(float %x, float %z) {
242 ; CHECK-LABEL: @fmuladd_fneg_x_fneg_const(
243 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
244 ; CHECK-NEXT:    ret float [[FMULADD]]
246   %x.fneg = fsub float -0.0, %x
247   %fsub = fsub float -0.0, bitcast (i32 ptrtoint (ptr @external to i32) to float)
248   %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %fsub, float %z)
249   ret float %fmuladd
252 define float @fmuladd_unary_fneg_x_unary_fneg_const(float %x, float %z) {
253 ; CHECK-LABEL: @fmuladd_unary_fneg_x_unary_fneg_const(
254 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (ptr @external to i32) to float), float [[Z:%.*]])
255 ; CHECK-NEXT:    ret float [[FMULADD]]
257   %x.fneg = fneg float %x
258   %external.fneg = fneg float bitcast (i32 ptrtoint (ptr @external to i32) to float)
259   %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %external.fneg, float %z)
260   ret float %fmuladd
263 define float @fmuladd_fabs_x_fabs_y(float %x, float %y, float %z) {
264 ; CHECK-LABEL: @fmuladd_fabs_x_fabs_y(
265 ; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
266 ; CHECK-NEXT:    [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])
267 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]])
268 ; CHECK-NEXT:    ret float [[FMULADD]]
270   %x.fabs = call float @llvm.fabs.f32(float %x)
271   %y.fabs = call float @llvm.fabs.f32(float %y)
272   %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %y.fabs, float %z)
273   ret float %fmuladd
276 define float @fmuladd_fabs_x_fabs_x(float %x, float %z) {
277 ; CHECK-LABEL: @fmuladd_fabs_x_fabs_x(
278 ; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])
279 ; CHECK-NEXT:    ret float [[FMULADD]]
281   %x.fabs = call float @llvm.fabs.f32(float %x)
282   %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z)
283   ret float %fmuladd
286 define float @fmuladd_fabs_x_fabs_x_fast(float %x, float %z) {
287 ; CHECK-LABEL: @fmuladd_fabs_x_fabs_x_fast(
288 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[X]]
289 ; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
290 ; CHECK-NEXT:    ret float [[FMULADD]]
292   %x.fabs = call float @llvm.fabs.f32(float %x)
293   %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z)
294   ret float %fmuladd
297 define float @fma_k_y_z(float %y, float %z) {
298 ; CHECK-LABEL: @fma_k_y_z(
299 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])
300 ; CHECK-NEXT:    ret float [[FMA]]
302   %fma = call float @llvm.fma.f32(float 4.0, float %y, float %z)
303   ret float %fma
306 define float @fma_k_y_z_fast(float %y, float %z) {
307 ; CHECK-LABEL: @fma_k_y_z_fast(
308 ; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])
309 ; CHECK-NEXT:    ret float [[FMA]]
311   %fma = call fast float @llvm.fma.f32(float 4.0, float %y, float %z)
312   ret float %fma
315 define float @fmuladd_k_y_z_fast(float %y, float %z) {
316 ; CHECK-LABEL: @fmuladd_k_y_z_fast(
317 ; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[Y:%.*]], 4.000000e+00
318 ; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
319 ; CHECK-NEXT:    ret float [[FMULADD]]
321   %fmuladd = call fast float @llvm.fmuladd.f32(float 4.0, float %y, float %z)
322   ret float %fmuladd
325 define float @fma_1_y_z(float %y, float %z) {
326 ; CHECK-LABEL: @fma_1_y_z(
327 ; CHECK-NEXT:    [[FMA:%.*]] = fadd float [[Y:%.*]], [[Z:%.*]]
328 ; CHECK-NEXT:    ret float [[FMA]]
330   %fma = call float @llvm.fma.f32(float 1.0, float %y, float %z)
331   ret float %fma
334 define float @fma_x_1_z(float %x, float %z) {
335 ; CHECK-LABEL: @fma_x_1_z(
336 ; CHECK-NEXT:    [[FMA:%.*]] = fadd float [[X:%.*]], [[Z:%.*]]
337 ; CHECK-NEXT:    ret float [[FMA]]
339   %fma = call float @llvm.fma.f32(float %x, float 1.0, float %z)
340   ret float %fma
343 define <2 x float> @fma_x_1_z_v2f32(<2 x float> %x, <2 x float> %z) {
344 ; CHECK-LABEL: @fma_x_1_z_v2f32(
345 ; CHECK-NEXT:    [[FMA:%.*]] = fadd <2 x float> [[X:%.*]], [[Z:%.*]]
346 ; CHECK-NEXT:    ret <2 x float> [[FMA]]
348   %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>, <2 x float> %z)
349   ret <2 x float> %fma
352 define <2 x float> @fma_x_1_2_z_v2f32(<2 x float> %x, <2 x float> %z) {
353 ; CHECK-LABEL: @fma_x_1_2_z_v2f32(
354 ; CHECK-NEXT:    [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 2.000000e+00>, <2 x float> [[Z:%.*]])
355 ; CHECK-NEXT:    ret <2 x float> [[FMA]]
357   %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 2.0>, <2 x float> %z)
358   ret <2 x float> %fma
361 define float @fma_x_1_z_fast(float %x, float %z) {
362 ; CHECK-LABEL: @fma_x_1_z_fast(
363 ; CHECK-NEXT:    [[FMA:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]
364 ; CHECK-NEXT:    ret float [[FMA]]
366   %fma = call fast float @llvm.fma.f32(float %x, float 1.0, float %z)
367   ret float %fma
370 define float @fma_1_1_z(float %z) {
371 ; CHECK-LABEL: @fma_1_1_z(
372 ; CHECK-NEXT:    [[FMA:%.*]] = fadd float [[Z:%.*]], 1.000000e+00
373 ; CHECK-NEXT:    ret float [[FMA]]
375   %fma = call float @llvm.fma.f32(float 1.0, float 1.0, float %z)
376   ret float %fma
379 define float @fma_x_y_0(float %x, float %y) {
380 ; CHECK-LABEL: @fma_x_y_0(
381 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float 0.000000e+00)
382 ; CHECK-NEXT:    ret float [[FMA]]
384   %fma = call float @llvm.fma.f32(float %x, float %y, float 0.0)
385   ret float %fma
388 define float @fma_x_y_0_nsz(float %x, float %y) {
389 ; CHECK-LABEL: @fma_x_y_0_nsz(
390 ; CHECK-NEXT:    [[FMA:%.*]] = fmul nsz float [[X:%.*]], [[Y:%.*]]
391 ; CHECK-NEXT:    ret float [[FMA]]
393   %fma = call nsz float @llvm.fma.f32(float %x, float %y, float 0.0)
394   ret float %fma
397 define <8 x half> @fma_x_y_0_v(<8 x half> %x, <8 x half> %y) {
398 ; CHECK-LABEL: @fma_x_y_0_v(
399 ; CHECK-NEXT:    [[FMA:%.*]] = call <8 x half> @llvm.fma.v8f16(<8 x half> [[X:%.*]], <8 x half> [[Y:%.*]], <8 x half> zeroinitializer)
400 ; CHECK-NEXT:    ret <8 x half> [[FMA]]
402   %fma = call <8 x half> @llvm.fma.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> zeroinitializer)
403   ret <8 x half> %fma
406 define <8 x half> @fma_x_y_0_nsz_v(<8 x half> %x, <8 x half> %y) {
407 ; CHECK-LABEL: @fma_x_y_0_nsz_v(
408 ; CHECK-NEXT:    [[FMA:%.*]] = fmul nsz <8 x half> [[X:%.*]], [[Y:%.*]]
409 ; CHECK-NEXT:    ret <8 x half> [[FMA]]
411   %fma = call nsz <8 x half> @llvm.fma.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> zeroinitializer)
412   ret <8 x half> %fma
415 define float @fmuladd_x_y_0(float %x, float %y) {
416 ; CHECK-LABEL: @fmuladd_x_y_0(
417 ; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float 0.000000e+00)
418 ; CHECK-NEXT:    ret float [[FMA]]
420   %fma = call float @llvm.fmuladd.f32(float %x, float %y, float 0.0)
421   ret float %fma
424 define float @fmuladd_x_y_0_nsz(float %x, float %y) {
425 ; CHECK-LABEL: @fmuladd_x_y_0_nsz(
426 ; CHECK-NEXT:    [[FMA:%.*]] = fmul nsz float [[X:%.*]], [[Y:%.*]]
427 ; CHECK-NEXT:    ret float [[FMA]]
429   %fma = call nsz float @llvm.fmuladd.f32(float %x, float %y, float 0.0)
430   ret float %fma
433 define float @fma_x_y_m0(float %x, float %y) {
434 ; CHECK-LABEL: @fma_x_y_m0(
435 ; CHECK-NEXT:    [[FMA:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
436 ; CHECK-NEXT:    ret float [[FMA]]
438   %fma = call float @llvm.fma.f32(float %x, float %y, float -0.0)
439   ret float %fma
442 define <8 x half> @fma_x_y_m0_v(<8 x half> %x, <8 x half> %y) {
443 ; CHECK-LABEL: @fma_x_y_m0_v(
444 ; CHECK-NEXT:    [[FMA:%.*]] = fmul <8 x half> [[X:%.*]], [[Y:%.*]]
445 ; CHECK-NEXT:    ret <8 x half> [[FMA]]
447   %fma = call <8 x half> @llvm.fma.v8f16(<8 x half> %x, <8 x half> %y, <8 x half> <half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0, half -0.0>)
448   ret <8 x half> %fma
451 define float @fmuladd_x_y_m0(float %x, float %y) {
452 ; CHECK-LABEL: @fmuladd_x_y_m0(
453 ; CHECK-NEXT:    [[FMA:%.*]] = fmul float [[X:%.*]], [[Y:%.*]]
454 ; CHECK-NEXT:    ret float [[FMA]]
456   %fma = call float @llvm.fmuladd.f32(float %x, float %y, float -0.0)
457   ret float %fma
460 define float @fmuladd_x_1_z_fast(float %x, float %z) {
461 ; CHECK-LABEL: @fmuladd_x_1_z_fast(
462 ; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]
463 ; CHECK-NEXT:    ret float [[FMULADD]]
465   %fmuladd = call fast float @llvm.fmuladd.f32(float %x, float 1.0, float %z)
466   ret float %fmuladd
469 define <2 x double> @fmuladd_a_0_b(<2 x double> %a, <2 x double> %b) {
470 ; CHECK-LABEL: @fmuladd_a_0_b(
471 ; CHECK-NEXT:    ret <2 x double> [[B:%.*]]
473   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %a, <2 x double> zeroinitializer, <2 x double> %b)
474   ret <2 x double> %res
477 define <2 x double> @fmuladd_0_a_b(<2 x double> %a, <2 x double> %b) {
478 ; CHECK-LABEL: @fmuladd_0_a_b(
479 ; CHECK-NEXT:    ret <2 x double> [[B:%.*]]
481   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> zeroinitializer, <2 x double> %a, <2 x double> %b)
482   ret <2 x double> %res
485 define <2 x double> @fmuladd_a_0_b_missing_flags(<2 x double> %a, <2 x double> %b) {
486 ; CHECK-LABEL: @fmuladd_a_0_b_missing_flags(
487 ; CHECK-NEXT:    [[RES:%.*]] = call nnan <2 x double> @llvm.fmuladd.v2f64(<2 x double> [[A:%.*]], <2 x double> zeroinitializer, <2 x double> [[B:%.*]])
488 ; CHECK-NEXT:    ret <2 x double> [[RES]]
490   %res = call nnan <2 x double> @llvm.fmuladd.v2f64(<2 x double> %a, <2 x double> zeroinitializer, <2 x double> %b)
491   ret <2 x double> %res
494 define <2 x double> @fma_a_0_b(<2 x double> %a, <2 x double> %b) {
495 ; CHECK-LABEL: @fma_a_0_b(
496 ; CHECK-NEXT:    ret <2 x double> [[B:%.*]]
498   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> zeroinitializer, <2 x double> %b)
499   ret <2 x double> %res
502 define <2 x double> @fma_0_a_b(<2 x double> %a, <2 x double> %b) {
503 ; CHECK-LABEL: @fma_0_a_b(
504 ; CHECK-NEXT:    ret <2 x double> [[B:%.*]]
506   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> zeroinitializer, <2 x double> %a, <2 x double> %b)
507   ret <2 x double> %res
510 define <2 x double> @fma_0_a_b_missing_flags(<2 x double> %a, <2 x double> %b) {
511 ; CHECK-LABEL: @fma_0_a_b_missing_flags(
512 ; CHECK-NEXT:    [[RES:%.*]] = call nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[A:%.*]], <2 x double> zeroinitializer, <2 x double> [[B:%.*]])
513 ; CHECK-NEXT:    ret <2 x double> [[RES]]
515   %res = call nsz <2 x double> @llvm.fma.v2f64(<2 x double> zeroinitializer, <2 x double> %a, <2 x double> %b)
516   ret <2 x double> %res
519 define <2 x double> @fma_sqrt(<2 x double> %a, <2 x double> %b) {
520 ; CHECK-LABEL: @fma_sqrt(
521 ; CHECK-NEXT:    [[RES:%.*]] = fadd fast <2 x double> [[A:%.*]], [[B:%.*]]
522 ; CHECK-NEXT:    ret <2 x double> [[RES]]
524   %sqrt = call fast <2 x double> @llvm.sqrt.v2f64(<2 x double> %a)
525   %res = call fast <2 x double> @llvm.fma.v2f64(<2 x double> %sqrt, <2 x double> %sqrt, <2 x double> %b)
526   ret <2 x double> %res
529 ; We do not fold constant multiplies in FMAs, as they could require rounding, unless either constant is 0.0 or 1.0.
530 define <2 x double> @fma_const_fmul(<2 x double> %b) {
531 ; CHECK-LABEL: @fma_const_fmul(
532 ; CHECK-NEXT:    [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0x4131233302898702, double 0x40C387800000D6C0>, <2 x double> <double 1.291820e-08, double 9.123000e-06>, <2 x double> [[B:%.*]])
533 ; CHECK-NEXT:    ret <2 x double> [[RES]]
535   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)
536   ret <2 x double> %res
539 define <2 x double> @fma_const_fmul_zero(<2 x double> %b) {
540 ; CHECK-LABEL: @fma_const_fmul_zero(
541 ; CHECK-NEXT:    ret <2 x double> [[B:%.*]]
543   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0.0, double 0.0>, <2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> %b)
544   ret <2 x double> %res
547 define <2 x double> @fma_const_fmul_zero2(<2 x double> %b) {
548 ; CHECK-LABEL: @fma_const_fmul_zero2(
549 ; CHECK-NEXT:    ret <2 x double> [[B:%.*]]
551   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 0.0, double 0.0>, <2 x double> %b)
552   ret <2 x double> %res
555 define <2 x double> @fma_const_fmul_one(<2 x double> %b) {
556 ; CHECK-LABEL: @fma_const_fmul_one(
557 ; CHECK-NEXT:    [[RES:%.*]] = fadd nnan nsz <2 x double> [[B:%.*]], <double 0x4131233302898702, double 0x40C387800000D6C0>
558 ; CHECK-NEXT:    ret <2 x double> [[RES]]
560   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> %b)
561   ret <2 x double> %res
564 define <2 x double> @fma_const_fmul_one2(<2 x double> %b) {
565 ; CHECK-LABEL: @fma_const_fmul_one2(
566 ; CHECK-NEXT:    [[RES:%.*]] = fadd nnan nsz <2 x double> [[B:%.*]], <double 0x4131233302898702, double 0x40C387800000D6C0>
567 ; CHECK-NEXT:    ret <2 x double> [[RES]]
569   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 1.0, double 1.0>, <2 x double> %b)
570   ret <2 x double> %res
573 define <2 x double> @fma_nan_and_const_0(<2 x double> %b) {
574 ; CHECK-LABEL: @fma_nan_and_const_0(
575 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
577   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)
578   ret <2 x double> %res
581 define <2 x double> @fma_nan_and_const_1(<2 x double> %b) {
582 ; CHECK-LABEL: @fma_nan_and_const_1(
583 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
585   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b)
586   ret <2 x double> %res
589 define <2 x double> @fma_nan_and_const_2(<2 x double> %b) {
590 ; CHECK-LABEL: @fma_nan_and_const_2(
591 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
593   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)
594   ret <2 x double> %res
597 define <2 x double> @fma_undef_0(<2 x double> %b, <2 x double> %c) {
598 ; CHECK-LABEL: @fma_undef_0(
599 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
601   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double undef, double undef>, <2 x double> %b, <2 x double> %c)
602   ret <2 x double> %res
605 define <2 x double> @fma_undef_1(<2 x double> %b, <2 x double> %c) {
606 ; CHECK-LABEL: @fma_undef_1(
607 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
609   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> <double undef, double undef>, <2 x double> %c)
610   ret <2 x double> %res
613 define <2 x double> @fma_undef_2(<2 x double> %b, <2 x double> %c) {
614 ; CHECK-LABEL: @fma_undef_2(
615 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
617   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double undef, double undef>)
618   ret <2 x double> %res
621 define <2 x double> @fma_partial_undef_0(<2 x double> %b, <2 x double> %c) {
622 ; CHECK-LABEL: @fma_partial_undef_0(
623 ; CHECK-NEXT:    [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[B:%.*]], <2 x double> <double undef, double 0x4068E00A137F38C5>, <2 x double> [[C:%.*]])
624 ; CHECK-NEXT:    ret <2 x double> [[RES]]
626   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double undef, double 199.00123>, <2 x double> %b, <2 x double> %c)
627   ret <2 x double> %res
630 define <2 x double> @fma_partial_undef_1(<2 x double> %b, <2 x double> %c) {
631 ; CHECK-LABEL: @fma_partial_undef_1(
632 ; CHECK-NEXT:    [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[B:%.*]], <2 x double> <double 0x4068E00A137F38C5, double undef>, <2 x double> [[C:%.*]])
633 ; CHECK-NEXT:    ret <2 x double> [[RES]]
635   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> <double 199.00123, double undef>, <2 x double> %c)
636   ret <2 x double> %res
639 define <2 x double> @fma_partial_undef_2(<2 x double> %b, <2 x double> %c) {
640 ; CHECK-LABEL: @fma_partial_undef_2(
641 ; CHECK-NEXT:    [[RES:%.*]] = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> [[B:%.*]], <2 x double> [[C:%.*]], <2 x double> <double 0x4068E00A137F38C5, double undef>)
642 ; CHECK-NEXT:    ret <2 x double> [[RES]]
644   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double 199.00123, double undef>)
645   ret <2 x double> %res
649 define <2 x double> @fma_nan_0(<2 x double> %b, <2 x double> %c) {
650 ; CHECK-LABEL: @fma_nan_0(
651 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
653   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b, <2 x double> %c)
654   ret <2 x double> %res
656 define <2 x double> @fma_nan_1(<2 x double> %b, <2 x double> %c) {
657 ; CHECK-LABEL: @fma_nan_1(
658 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
660   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %c)
661   ret <2 x double> %res
664 define <2 x double> @fma_nan_2(<2 x double> %b, <2 x double> %c) {
665 ; CHECK-LABEL: @fma_nan_2(
666 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
668   %res = call nnan nsz <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)
669   ret <2 x double> %res
672 define <2 x double> @fmuladd_const_fmul(<2 x double> %b) {
673 ; CHECK-LABEL: @fmuladd_const_fmul(
674 ; CHECK-NEXT:    [[RES:%.*]] = fadd nnan nsz <2 x double> [[B:%.*]], <double 0x3F8DB6C076AD949B, double 0x3FB75A405B6E6D69>
675 ; CHECK-NEXT:    ret <2 x double> [[RES]]
677   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 1123123.0099110012314, double 9999.0000001>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)
678   ret <2 x double> %res
681 define <2 x double> @fmuladd_nan_and_const_0(<2 x double> %b) {
682 ; CHECK-LABEL: @fmuladd_nan_and_const_0(
683 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
685   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b)
686   ret <2 x double> %res
689 define <2 x double> @fmuladd_nan_and_const_1(<2 x double> %b) {
690 ; CHECK-LABEL: @fmuladd_nan_and_const_1(
691 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
693   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b)
694   ret <2 x double> %res
697 define <2 x double> @fmuladd_nan_and_const_2(<2 x double> %b) {
698 ; CHECK-LABEL: @fmuladd_nan_and_const_2(
699 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
701   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0.0000000129182, double 0.000009123>, <2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)
702   ret <2 x double> %res
705 define <2 x double> @fmuladd_nan_0(<2 x double> %b, <2 x double> %c) {
706 ; CHECK-LABEL: @fmuladd_nan_0(
707 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
709   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %b, <2 x double> %c)
710   ret <2 x double> %res
713 define <2 x double> @fmuladd_nan_1(<2 x double> %b, <2 x double> %c) {
714 ; CHECK-LABEL: @fmuladd_nan_1(
715 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
717   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %b, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>, <2 x double> %c)
718   ret <2 x double> %res
721 define <2 x double> @fmuladd_undef_0(<2 x double> %b, <2 x double> %c) {
722 ; CHECK-LABEL: @fmuladd_undef_0(
723 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
725   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> <double undef, double undef>, <2 x double> %b, <2 x double> %c)
726   ret <2 x double> %res
729 define <2 x double> @fmuladd_undef_1(<2 x double> %b, <2 x double> %c) {
730 ; CHECK-LABEL: @fmuladd_undef_1(
731 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
733   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %b, <2 x double> <double undef, double undef>, <2 x double> %c)
734   ret <2 x double> %res
737 define <2 x double> @fmuladd_undef_2(<2 x double> %b, <2 x double> %c) {
738 ; CHECK-LABEL: @fmuladd_undef_2(
739 ; CHECK-NEXT:    ret <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>
741   %res = call nnan nsz <2 x double> @llvm.fmuladd.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> <double 0x7FF8000000000000, double 0x7FF8000000000000>)
742   ret <2 x double> %res
745 define <2 x float> @fma_unary_shuffle_ops(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
746 ; CHECK-LABEL: @fma_unary_shuffle_ops(
747 ; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
748 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
749 ; CHECK-NEXT:    ret <2 x float> [[R]]
751   %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>
752   %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>
753   %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>
754   %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)
755   ret <2 x float> %r
758 define <3 x float> @fma_unary_shuffle_ops_widening(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
759 ; CHECK-LABEL: @fma_unary_shuffle_ops_widening(
760 ; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
761 ; CHECK-NEXT:    call void @use_vec3(<3 x float> [[A]])
762 ; CHECK-NEXT:    [[TMP1:%.*]] = call fast <2 x float> @llvm.fma.v2f32(<2 x float> [[X]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
763 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
764 ; CHECK-NEXT:    ret <3 x float> [[R]]
766   %a = shufflevector <2 x float> %x, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
767   call void @use_vec3(<3 x float> %a)
768   %b = shufflevector <2 x float> %y, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
769   %c = shufflevector <2 x float> %z, <2 x float> poison, <3 x i32> <i32 1, i32 0, i32 1>
770   %r = call fast <3 x float> @llvm.fma.v3f32(<3 x float> %a, <3 x float> %b, <3 x float> %c)
771   ret <3 x float> %r
774 define <2 x float> @fma_unary_shuffle_ops_narrowing(<3 x float> %x, <3 x float> %y, <3 x float> %z) {
775 ; CHECK-LABEL: @fma_unary_shuffle_ops_narrowing(
776 ; CHECK-NEXT:    [[B:%.*]] = shufflevector <3 x float> [[Y:%.*]], <3 x float> poison, <2 x i32> <i32 1, i32 0>
777 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[B]])
778 ; CHECK-NEXT:    [[TMP1:%.*]] = call nnan nsz <3 x float> @llvm.fma.v3f32(<3 x float> [[X:%.*]], <3 x float> [[Y]], <3 x float> [[Z:%.*]])
779 ; CHECK-NEXT:    [[R:%.*]] = shufflevector <3 x float> [[TMP1]], <3 x float> poison, <2 x i32> <i32 1, i32 0>
780 ; CHECK-NEXT:    ret <2 x float> [[R]]
782   %a = shufflevector <3 x float> %x, <3 x float> poison, <2 x i32> <i32 1, i32 0>
783   %b = shufflevector <3 x float> %y, <3 x float> poison, <2 x i32> <i32 1, i32 0>
784   call void @use_vec(<2 x float> %b)
785   %c = shufflevector <3 x float> %z, <3 x float> poison, <2 x i32> <i32 1, i32 0>
786   %r = call nnan nsz <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)
787   ret <2 x float> %r
790 ; negative test - must have 3 shuffles
792 define <2 x float> @fma_unary_shuffle_ops_unshuffled(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
793 ; CHECK-LABEL: @fma_unary_shuffle_ops_unshuffled(
794 ; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
795 ; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
796 ; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[Z:%.*]])
797 ; CHECK-NEXT:    ret <2 x float> [[R]]
799   %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>
800   %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>
801   %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %z)
802   ret <2 x float> %r
805 ; negative test - must have identical masks
807 define <2 x float> @fma_unary_shuffle_ops_wrong_mask(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
808 ; CHECK-LABEL: @fma_unary_shuffle_ops_wrong_mask(
809 ; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
810 ; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> zeroinitializer
811 ; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x float> [[Z:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
812 ; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[C]])
813 ; CHECK-NEXT:    ret <2 x float> [[R]]
815   %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>
816   %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 0, i32 0>
817   %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>
818   %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)
819   ret <2 x float> %r
822 ; negative test - too many uses
824 define <2 x float> @fma_unary_shuffle_ops_uses(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
825 ; CHECK-LABEL: @fma_unary_shuffle_ops_uses(
826 ; CHECK-NEXT:    [[A:%.*]] = shufflevector <2 x float> [[X:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
827 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[A]])
828 ; CHECK-NEXT:    [[B:%.*]] = shufflevector <2 x float> [[Y:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
829 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[B]])
830 ; CHECK-NEXT:    [[C:%.*]] = shufflevector <2 x float> [[Z:%.*]], <2 x float> poison, <2 x i32> <i32 1, i32 0>
831 ; CHECK-NEXT:    call void @use_vec(<2 x float> [[C]])
832 ; CHECK-NEXT:    [[R:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[A]], <2 x float> [[B]], <2 x float> [[C]])
833 ; CHECK-NEXT:    ret <2 x float> [[R]]
835   %a = shufflevector <2 x float> %x, <2 x float> poison, <2 x i32> <i32 1, i32 0>
836   call void @use_vec(<2 x float> %a)
837   %b = shufflevector <2 x float> %y, <2 x float> poison, <2 x i32> <i32 1, i32 0>
838   call void @use_vec(<2 x float> %b)
839   %c = shufflevector <2 x float> %z, <2 x float> poison, <2 x i32> <i32 1, i32 0>
840   call void @use_vec(<2 x float> %c)
841   %r = call <2 x float> @llvm.fma.v2f32(<2 x float> %a, <2 x float> %b, <2 x float> %c)
842   ret <2 x float> %r