1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -instcombine < %s | FileCheck %s
3
4declare float @llvm.fma.f32(float, float, float) #1
5declare <2 x float> @llvm.fma.v2f32(<2 x float>, <2 x float>, <2 x float>) #1
6declare float @llvm.fmuladd.f32(float, float, float) #1
7declare float @llvm.fabs.f32(float) #1
8
9@external = external global i32
10
11define float @fma_fneg_x_fneg_y(float %x, float %y, float %z) {
12; CHECK-LABEL: @fma_fneg_x_fneg_y(
13; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
14; CHECK-NEXT:    ret float [[FMA]]
15;
16  %x.fneg = fsub float -0.0, %x
17  %y.fneg = fsub float -0.0, %y
18  %fma = call float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)
19  ret float %fma
20}
21
22define <2 x float> @fma_fneg_x_fneg_y_vec(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
23; CHECK-LABEL: @fma_fneg_x_fneg_y_vec(
24; CHECK-NEXT:    [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
25; CHECK-NEXT:    ret <2 x float> [[FMA]]
26;
27  %xn = fsub <2 x float> <float -0.0, float -0.0>, %x
28  %yn = fsub <2 x float> <float -0.0, float -0.0>, %y
29  %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
30  ret <2 x float> %fma
31}
32
33define <2 x float> @fma_fneg_x_fneg_y_vec_undef(<2 x float> %x, <2 x float> %y, <2 x float> %z) {
34; CHECK-LABEL: @fma_fneg_x_fneg_y_vec_undef(
35; CHECK-NEXT:    [[FMA:%.*]] = call <2 x float> @llvm.fma.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]], <2 x float> [[Z:%.*]])
36; CHECK-NEXT:    ret <2 x float> [[FMA]]
37;
38  %xn = fsub <2 x float> <float -0.0, float undef>, %x
39  %yn = fsub <2 x float> <float undef, float -0.0>, %y
40  %fma = call <2 x float> @llvm.fma.v2f32(<2 x float> %xn, <2 x float> %yn, <2 x float> %z)
41  ret <2 x float> %fma
42}
43
44define float @fma_fneg_x_fneg_y_fast(float %x, float %y, float %z) {
45; CHECK-LABEL: @fma_fneg_x_fneg_y_fast(
46; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
47; CHECK-NEXT:    ret float [[FMA]]
48;
49  %x.fneg = fsub float -0.0, %x
50  %y.fneg = fsub float -0.0, %y
51  %fma = call fast float @llvm.fma.f32(float %x.fneg, float %y.fneg, float %z)
52  ret float %fma
53}
54
55define float @fma_fneg_const_fneg_y(float %y, float %z) {
56; CHECK-LABEL: @fma_fneg_const_fneg_y(
57; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]])
58; CHECK-NEXT:    ret float [[FMA]]
59;
60  %y.fneg = fsub float -0.0, %y
61  %fma = call float @llvm.fma.f32(float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %y.fneg, float %z)
62  ret float %fma
63}
64
65define float @fma_fneg_x_fneg_const(float %x, float %z) {
66; CHECK-LABEL: @fma_fneg_x_fneg_const(
67; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]])
68; CHECK-NEXT:    ret float [[FMA]]
69;
70  %x.fneg = fsub float -0.0, %x
71  %fma = call float @llvm.fma.f32(float %x.fneg, float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %z)
72  ret float %fma
73}
74
75define float @fma_fabs_x_fabs_y(float %x, float %y, float %z) {
76; CHECK-LABEL: @fma_fabs_x_fabs_y(
77; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
78; CHECK-NEXT:    [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])
79; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]])
80; CHECK-NEXT:    ret float [[FMA]]
81;
82  %x.fabs = call float @llvm.fabs.f32(float %x)
83  %y.fabs = call float @llvm.fabs.f32(float %y)
84  %fma = call float @llvm.fma.f32(float %x.fabs, float %y.fabs, float %z)
85  ret float %fma
86}
87
88define float @fma_fabs_x_fabs_x(float %x, float %z) {
89; CHECK-LABEL: @fma_fabs_x_fabs_x(
90; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])
91; CHECK-NEXT:    ret float [[FMA]]
92;
93  %x.fabs = call float @llvm.fabs.f32(float %x)
94  %fma = call float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z)
95  ret float %fma
96}
97
98define float @fma_fabs_x_fabs_x_fast(float %x, float %z) {
99; CHECK-LABEL: @fma_fabs_x_fabs_x_fast(
100; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])
101; CHECK-NEXT:    ret float [[FMA]]
102;
103  %x.fabs = call float @llvm.fabs.f32(float %x)
104  %fma = call fast float @llvm.fma.f32(float %x.fabs, float %x.fabs, float %z)
105  ret float %fma
106}
107
108define float @fmuladd_fneg_x_fneg_y(float %x, float %y, float %z) {
109; CHECK-LABEL: @fmuladd_fneg_x_fneg_y(
110; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[Y:%.*]], float [[Z:%.*]])
111; CHECK-NEXT:    ret float [[FMULADD]]
112;
113  %x.fneg = fsub float -0.0, %x
114  %y.fneg = fsub float -0.0, %y
115  %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)
116  ret float %fmuladd
117}
118
119define float @fmuladd_fneg_x_fneg_y_fast(float %x, float %y, float %z) {
120; CHECK-LABEL: @fmuladd_fneg_x_fneg_y_fast(
121; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[Y:%.*]]
122; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
123; CHECK-NEXT:    ret float [[FMULADD]]
124;
125  %x.fneg = fsub float -0.0, %x
126  %y.fneg = fsub float -0.0, %y
127  %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fneg, float %y.fneg, float %z)
128  ret float %fmuladd
129}
130
131define float @fmuladd_fneg_const_fneg_y(float %y, float %z) {
132; CHECK-LABEL: @fmuladd_fneg_const_fneg_y(
133; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[Y:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]])
134; CHECK-NEXT:    ret float [[FMULADD]]
135;
136  %y.fneg = fsub float -0.0, %y
137  %fmuladd = call float @llvm.fmuladd.f32(float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %y.fneg, float %z)
138  ret float %fmuladd
139}
140
141define float @fmuladd_fneg_x_fneg_const(float %x, float %z) {
142; CHECK-LABEL: @fmuladd_fneg_x_fneg_const(
143; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float bitcast (i32 ptrtoint (i32* @external to i32) to float), float [[Z:%.*]])
144; CHECK-NEXT:    ret float [[FMULADD]]
145;
146  %x.fneg = fsub float -0.0, %x
147  %fmuladd = call float @llvm.fmuladd.f32(float %x.fneg, float fsub (float -0.0, float bitcast (i32 ptrtoint (i32* @external to i32) to float)), float %z)
148  ret float %fmuladd
149}
150
151define float @fmuladd_fabs_x_fabs_y(float %x, float %y, float %z) {
152; CHECK-LABEL: @fmuladd_fabs_x_fabs_y(
153; CHECK-NEXT:    [[X_FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
154; CHECK-NEXT:    [[Y_FABS:%.*]] = call float @llvm.fabs.f32(float [[Y:%.*]])
155; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X_FABS]], float [[Y_FABS]], float [[Z:%.*]])
156; CHECK-NEXT:    ret float [[FMULADD]]
157;
158  %x.fabs = call float @llvm.fabs.f32(float %x)
159  %y.fabs = call float @llvm.fabs.f32(float %y)
160  %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %y.fabs, float %z)
161  ret float %fmuladd
162}
163
164define float @fmuladd_fabs_x_fabs_x(float %x, float %z) {
165; CHECK-LABEL: @fmuladd_fabs_x_fabs_x(
166; CHECK-NEXT:    [[FMULADD:%.*]] = call float @llvm.fmuladd.f32(float [[X:%.*]], float [[X]], float [[Z:%.*]])
167; CHECK-NEXT:    ret float [[FMULADD]]
168;
169  %x.fabs = call float @llvm.fabs.f32(float %x)
170  %fmuladd = call float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z)
171  ret float %fmuladd
172}
173
174define float @fmuladd_fabs_x_fabs_x_fast(float %x, float %z) {
175; CHECK-LABEL: @fmuladd_fabs_x_fabs_x_fast(
176; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[X:%.*]], [[X]]
177; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
178; CHECK-NEXT:    ret float [[FMULADD]]
179;
180  %x.fabs = call float @llvm.fabs.f32(float %x)
181  %fmuladd = call fast float @llvm.fmuladd.f32(float %x.fabs, float %x.fabs, float %z)
182  ret float %fmuladd
183}
184
185define float @fma_k_y_z(float %y, float %z) {
186; CHECK-LABEL: @fma_k_y_z(
187; CHECK-NEXT:    [[FMA:%.*]] = call float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])
188; CHECK-NEXT:    ret float [[FMA]]
189;
190  %fma = call float @llvm.fma.f32(float 4.0, float %y, float %z)
191  ret float %fma
192}
193
194define float @fma_k_y_z_fast(float %y, float %z) {
195; CHECK-LABEL: @fma_k_y_z_fast(
196; CHECK-NEXT:    [[FMA:%.*]] = call fast float @llvm.fma.f32(float [[Y:%.*]], float 4.000000e+00, float [[Z:%.*]])
197; CHECK-NEXT:    ret float [[FMA]]
198;
199  %fma = call fast float @llvm.fma.f32(float 4.0, float %y, float %z)
200  ret float %fma
201}
202
203define float @fmuladd_k_y_z_fast(float %y, float %z) {
204; CHECK-LABEL: @fmuladd_k_y_z_fast(
205; CHECK-NEXT:    [[TMP1:%.*]] = fmul fast float [[Y:%.*]], 4.000000e+00
206; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[TMP1]], [[Z:%.*]]
207; CHECK-NEXT:    ret float [[FMULADD]]
208;
209  %fmuladd = call fast float @llvm.fmuladd.f32(float 4.0, float %y, float %z)
210  ret float %fmuladd
211}
212
213define float @fma_1_y_z(float %y, float %z) {
214; CHECK-LABEL: @fma_1_y_z(
215; CHECK-NEXT:    [[FMA:%.*]] = fadd float [[Y:%.*]], [[Z:%.*]]
216; CHECK-NEXT:    ret float [[FMA]]
217;
218  %fma = call float @llvm.fma.f32(float 1.0, float %y, float %z)
219  ret float %fma
220}
221
222define float @fma_x_1_z(float %x, float %z) {
223; CHECK-LABEL: @fma_x_1_z(
224; CHECK-NEXT:    [[FMA:%.*]] = fadd float [[X:%.*]], [[Z:%.*]]
225; CHECK-NEXT:    ret float [[FMA]]
226;
227  %fma = call float @llvm.fma.f32(float %x, float 1.0, float %z)
228  ret float %fma
229}
230
231define <2 x float> @fma_x_1_z_v2f32(<2 x float> %x, <2 x float> %z) {
232; CHECK-LABEL: @fma_x_1_z_v2f32(
233; CHECK-NEXT:    [[FMA:%.*]] = fadd <2 x float> [[X:%.*]], [[Z:%.*]]
234; CHECK-NEXT:    ret <2 x float> [[FMA]]
235;
236  %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)
237  ret <2 x float> %fma
238}
239
240define <2 x float> @fma_x_1_2_z_v2f32(<2 x float> %x, <2 x float> %z) {
241; CHECK-LABEL: @fma_x_1_2_z_v2f32(
242; 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:%.*]])
243; CHECK-NEXT:    ret <2 x float> [[FMA]]
244;
245  %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)
246  ret <2 x float> %fma
247}
248
249define float @fma_x_1_z_fast(float %x, float %z) {
250; CHECK-LABEL: @fma_x_1_z_fast(
251; CHECK-NEXT:    [[FMA:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]
252; CHECK-NEXT:    ret float [[FMA]]
253;
254  %fma = call fast float @llvm.fma.f32(float %x, float 1.0, float %z)
255  ret float %fma
256}
257
258define float @fma_1_1_z(float %z) {
259; CHECK-LABEL: @fma_1_1_z(
260; CHECK-NEXT:    [[FMA:%.*]] = fadd float [[Z:%.*]], 1.000000e+00
261; CHECK-NEXT:    ret float [[FMA]]
262;
263  %fma = call float @llvm.fma.f32(float 1.0, float 1.0, float %z)
264  ret float %fma
265}
266
267define float @fmuladd_x_1_z_fast(float %x, float %z) {
268; CHECK-LABEL: @fmuladd_x_1_z_fast(
269; CHECK-NEXT:    [[FMULADD:%.*]] = fadd fast float [[X:%.*]], [[Z:%.*]]
270; CHECK-NEXT:    ret float [[FMULADD]]
271;
272  %fmuladd = call fast float @llvm.fmuladd.f32(float %x, float 1.0, float %z)
273  ret float %fmuladd
274}
275
276attributes #0 = { nounwind }
277attributes #1 = { nounwind readnone }
278