xref: /llvm-project/llvm/test/Transforms/InstCombine/fcmp-fadd-select.ll (revision 76a4c4593ba9f8cad894d80ea75687cd86be3cdd)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; fcmp OGT + fadd + sel => fcmp OGT + sel => fmaxnum
5
6define float @test_fcmp_ogt_fadd_select_constant(float %in) {
7; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_constant(
8; CHECK-SAME: float [[IN:%.*]]) {
9; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
10; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
11; CHECK-NEXT:    ret float [[ADD_NEW]]
12;
13  %cmp1 = fcmp ogt float %in, 0.000000e+00
14  %add = fadd float %in, 1.000000e+00
15  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
16  ret float %sel
17}
18
19define float @test_fcmp_ogt_fadd_select_constant_swapped(float %in) {
20; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_constant_swapped(
21; CHECK-SAME: float [[IN:%.*]]) {
22; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
23; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
24; CHECK-NEXT:    ret float [[ADD_NEW]]
25;
26  %cmp1 = fcmp ogt float %in, 0.000000e+00
27  %add = fadd float %in, 1.000000e+00
28  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
29  ret float %sel
30}
31
32define float @test_fcmp_ogt_fadd_select_neg_constant(float %in) {
33; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_neg_constant(
34; CHECK-SAME: float [[IN:%.*]]) {
35; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
36; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
37; CHECK-NEXT:    ret float [[ADD_NEW]]
38;
39  %cmp1 = fcmp ogt float %in, -0.000000e+00
40  %add = fadd float %in, 1.000000e+00
41  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
42  ret float %sel
43}
44
45define float @test_fcmp_ogt_fadd_select_fastmath_preserve(float %in) {
46; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_fastmath_preserve(
47; CHECK-SAME: float [[IN:%.*]]) {
48; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
49; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
50; CHECK-NEXT:    ret float [[ADD_NEW]]
51;
52  %cmp1 = fcmp ogt float %in, 0.000000e+00
53  %add = fadd nnan float %in, 1.000000e+00
54  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
55  ret float %sel
56}
57
58define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(<2 x float> %in) {
59; CHECK-LABEL: define <2 x float> @test_fcmp_ogt_fadd_select_constant_vectors(
60; CHECK-SAME: <2 x float> [[IN:%.*]]) {
61; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
62; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
63; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
64;
65  %cmp1 = fcmp ogt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
66  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
67  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
68  ret <2 x float> %sel
69}
70
71
72; fcmp OLT + fadd + sel => fcmp OLT + sel => fminnum
73
74define float @test_fcmp_olt_fadd_select_constant(float %in) {
75; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_constant(
76; CHECK-SAME: float [[IN:%.*]]) {
77; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
78; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
79; CHECK-NEXT:    ret float [[ADD_NEW]]
80;
81  %cmp1 = fcmp olt float %in, 0.000000e+00
82  %add = fadd float %in, 1.000000e+00
83  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
84  ret float %sel
85}
86
87define float @test_fcmp_olt_fadd_select_constant_swapped(float %in) {
88; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_constant_swapped(
89; CHECK-SAME: float [[IN:%.*]]) {
90; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
91; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
92; CHECK-NEXT:    ret float [[ADD_NEW]]
93;
94  %cmp1 = fcmp olt float %in, 0.000000e+00
95  %add = fadd float %in, 1.000000e+00
96  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
97  ret float %sel
98}
99
100define float @test_fcmp_olt_fadd_select_neg_constant(float %in) {
101; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_neg_constant(
102; CHECK-SAME: float [[IN:%.*]]) {
103; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
104; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
105; CHECK-NEXT:    ret float [[ADD_NEW]]
106;
107  %cmp1 = fcmp olt float %in, -0.000000e+00
108  %add = fadd float %in, 1.000000e+00
109  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
110  ret float %sel
111}
112
113define float @test_fcmp_olt_fadd_select_fastmath_preserve(float %in) {
114; CHECK-LABEL: define float @test_fcmp_olt_fadd_select_fastmath_preserve(
115; CHECK-SAME: float [[IN:%.*]]) {
116; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
117; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
118; CHECK-NEXT:    ret float [[ADD_NEW]]
119;
120  %cmp1 = fcmp olt float %in, 0.000000e+00
121  %add = fadd nnan float %in, 1.000000e+00
122  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
123  ret float %sel
124}
125
126define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(<2 x float> %in) {
127; CHECK-LABEL: define <2 x float> @test_fcmp_olt_fadd_select_constant_vectors(
128; CHECK-SAME: <2 x float> [[IN:%.*]]) {
129; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
130; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
131; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
132;
133  %cmp1 = fcmp olt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
134  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
135  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
136  ret <2 x float> %sel
137}
138
139
140; fcmp OGE + fadd + sel => fcmp OGE + sel => fmaxnum
141
142define float @test_fcmp_oge_fadd_select_constant(float %in) {
143; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_constant(
144; CHECK-SAME: float [[IN:%.*]]) {
145; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
146; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
147; CHECK-NEXT:    ret float [[ADD_NEW]]
148;
149  %cmp1 = fcmp oge float %in, 0.000000e+00
150  %add = fadd float %in, 1.000000e+00
151  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
152  ret float %sel
153}
154
155define float @test_fcmp_oge_fadd_select_constant_swapped(float %in) {
156; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_constant_swapped(
157; CHECK-SAME: float [[IN:%.*]]) {
158; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
159; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
160; CHECK-NEXT:    ret float [[ADD_NEW]]
161;
162  %cmp1 = fcmp oge float %in, 0.000000e+00
163  %add = fadd float %in, 1.000000e+00
164  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
165  ret float %sel
166}
167
168define float @test_fcmp_oge_fadd_select_neg_constant(float %in) {
169; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_neg_constant(
170; CHECK-SAME: float [[IN:%.*]]) {
171; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
172; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
173; CHECK-NEXT:    ret float [[ADD_NEW]]
174;
175  %cmp1 = fcmp oge float %in, -0.000000e+00
176  %add = fadd float %in, 1.000000e+00
177  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
178  ret float %sel
179}
180
181define float @test_fcmp_oge_fadd_select_fastmath_preserve(float %in) {
182; CHECK-LABEL: define float @test_fcmp_oge_fadd_select_fastmath_preserve(
183; CHECK-SAME: float [[IN:%.*]]) {
184; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
185; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
186; CHECK-NEXT:    ret float [[ADD_NEW]]
187;
188  %cmp1 = fcmp oge float %in, 0.000000e+00
189  %add = fadd nnan float %in, 1.000000e+00
190  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
191  ret float %sel
192}
193
194define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(<2 x float> %in) {
195; CHECK-LABEL: define <2 x float> @test_fcmp_oge_fadd_select_constant_vectors(
196; CHECK-SAME: <2 x float> [[IN:%.*]]) {
197; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
198; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
199; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
200;
201  %cmp1 = fcmp oge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
202  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
203  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
204  ret <2 x float> %sel
205}
206
207
208; fcmp OLE + fadd + sel => fcmp OLE + sel => fminnum
209
210define float @test_fcmp_ole_fadd_select_constant(float %in) {
211; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_constant(
212; CHECK-SAME: float [[IN:%.*]]) {
213; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
214; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
215; CHECK-NEXT:    ret float [[ADD_NEW]]
216;
217  %cmp1 = fcmp ole float %in, 0.000000e+00
218  %add = fadd float %in, 1.000000e+00
219  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
220  ret float %sel
221}
222
223define float @test_fcmp_ole_fadd_select_constant_swapped(float %in) {
224; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_constant_swapped(
225; CHECK-SAME: float [[IN:%.*]]) {
226; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
227; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
228; CHECK-NEXT:    ret float [[ADD_NEW]]
229;
230  %cmp1 = fcmp ole float %in, 0.000000e+00
231  %add = fadd float %in, 1.000000e+00
232  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
233  ret float %sel
234}
235
236define float @test_fcmp_ole_fadd_select_neg_constant(float %in) {
237; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_neg_constant(
238; CHECK-SAME: float [[IN:%.*]]) {
239; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
240; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
241; CHECK-NEXT:    ret float [[ADD_NEW]]
242;
243  %cmp1 = fcmp ole float %in, -0.000000e+00
244  %add = fadd float %in, 1.000000e+00
245  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
246  ret float %sel
247}
248
249define float @test_fcmp_ole_fadd_select_fastmath_preserve(float %in) {
250; CHECK-LABEL: define float @test_fcmp_ole_fadd_select_fastmath_preserve(
251; CHECK-SAME: float [[IN:%.*]]) {
252; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.minnum.f32(float [[IN]], float 0.000000e+00)
253; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
254; CHECK-NEXT:    ret float [[ADD_NEW]]
255;
256  %cmp1 = fcmp ole float %in, 0.000000e+00
257  %add = fadd nnan float %in, 1.000000e+00
258  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
259  ret float %sel
260}
261
262define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(<2 x float> %in) {
263; CHECK-LABEL: define <2 x float> @test_fcmp_ole_fadd_select_constant_vectors(
264; CHECK-SAME: <2 x float> [[IN:%.*]]) {
265; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[IN]], <2 x float> zeroinitializer)
266; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
267; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
268;
269  %cmp1 = fcmp ole <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
270  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
271  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
272  ret <2 x float> %sel
273}
274
275
276; fcmp UGT + fadd + sel => fcmp UGT + sel => fcmp OLE + sel
277
278define float @test_fcmp_ugt_fadd_select_constant(float %in) {
279; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_constant(
280; CHECK-SAME: float [[IN:%.*]]) {
281; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ole float [[IN]], 0.000000e+00
282; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
283; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
284; CHECK-NEXT:    ret float [[ADD_NEW]]
285;
286  %cmp1 = fcmp ugt float %in, 0.000000e+00
287  %add = fadd float %in, 1.000000e+00
288  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
289  ret float %sel
290}
291
292define float @test_fcmp_ugt_fadd_select_constant_swapped(float %in) {
293; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_constant_swapped(
294; CHECK-SAME: float [[IN:%.*]]) {
295; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ole float [[IN]], 0.000000e+00
296; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float [[IN]], float 0.000000e+00
297; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
298; CHECK-NEXT:    ret float [[ADD_NEW]]
299;
300  %cmp1 = fcmp ugt float %in, 0.000000e+00
301  %add = fadd float %in, 1.000000e+00
302  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
303  ret float %sel
304}
305
306define float @test_fcmp_ugt_fadd_select_neg_constant(float %in) {
307; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_neg_constant(
308; CHECK-SAME: float [[IN:%.*]]) {
309; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ole float [[IN]], 0.000000e+00
310; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
311; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
312; CHECK-NEXT:    ret float [[ADD_NEW]]
313;
314  %cmp1 = fcmp ugt float %in, -0.000000e+00
315  %add = fadd float %in, 1.000000e+00
316  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
317  ret float %sel
318}
319
320define float @test_fcmp_ugt_fadd_select_fastmath_preserve(float %in) {
321; CHECK-LABEL: define float @test_fcmp_ugt_fadd_select_fastmath_preserve(
322; CHECK-SAME: float [[IN:%.*]]) {
323; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ole float [[IN]], 0.000000e+00
324; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
325; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
326; CHECK-NEXT:    ret float [[ADD_NEW]]
327;
328  %cmp1 = fcmp ugt float %in, 0.000000e+00
329  %add = fadd nnan float %in, 1.000000e+00
330  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
331  ret float %sel
332}
333
334define <2 x float> @test_fcmp_ugt_fadd_select_constant_vectors(<2 x float> %in) {
335; CHECK-LABEL: define <2 x float> @test_fcmp_ugt_fadd_select_constant_vectors(
336; CHECK-SAME: <2 x float> [[IN:%.*]]) {
337; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ole <2 x float> [[IN]], zeroinitializer
338; CHECK-NEXT:    [[SEL_NEW:%.*]] = select <2 x i1> [[CMP1_INV]], <2 x float> zeroinitializer, <2 x float> [[IN]]
339; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
340; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
341;
342  %cmp1 = fcmp ugt <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
343  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
344  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
345  ret <2 x float> %sel
346}
347
348
349; fcmp UGE + fadd + sel => fcmp UGE + sel => fcmp olt + sel
350
351define float @test_fcmp_uge_fadd_select_constant(float %in) {
352; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_constant(
353; CHECK-SAME: float [[IN:%.*]]) {
354; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp olt float [[IN]], 0.000000e+00
355; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
356; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
357; CHECK-NEXT:    ret float [[ADD_NEW]]
358;
359  %cmp1 = fcmp uge float %in, 0.000000e+00
360  %add = fadd float %in, 1.000000e+00
361  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
362  ret float %sel
363}
364
365define float @test_fcmp_uge_fadd_select_constant_swapped(float %in) {
366; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_constant_swapped(
367; CHECK-SAME: float [[IN:%.*]]) {
368; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp olt float [[IN]], 0.000000e+00
369; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float [[IN]], float 0.000000e+00
370; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
371; CHECK-NEXT:    ret float [[ADD_NEW]]
372;
373  %cmp1 = fcmp uge float %in, 0.000000e+00
374  %add = fadd float %in, 1.000000e+00
375  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
376  ret float %sel
377}
378
379define float @test_fcmp_uge_fadd_select_neg_constant(float %in) {
380; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_neg_constant(
381; CHECK-SAME: float [[IN:%.*]]) {
382; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp olt float [[IN]], 0.000000e+00
383; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
384; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
385; CHECK-NEXT:    ret float [[ADD_NEW]]
386;
387  %cmp1 = fcmp uge float %in, -0.000000e+00
388  %add = fadd float %in, 1.000000e+00
389  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
390  ret float %sel
391}
392
393define float @test_fcmp_uge_fadd_select_fastmath_preserve(float %in) {
394; CHECK-LABEL: define float @test_fcmp_uge_fadd_select_fastmath_preserve(
395; CHECK-SAME: float [[IN:%.*]]) {
396; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp olt float [[IN]], 0.000000e+00
397; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
398; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
399; CHECK-NEXT:    ret float [[ADD_NEW]]
400;
401  %cmp1 = fcmp uge float %in, 0.000000e+00
402  %add = fadd nnan float %in, 1.000000e+00
403  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
404  ret float %sel
405}
406
407define <2 x float> @test_fcmp_uge_fadd_select_constant_vectors(<2 x float> %in) {
408; CHECK-LABEL: define <2 x float> @test_fcmp_uge_fadd_select_constant_vectors(
409; CHECK-SAME: <2 x float> [[IN:%.*]]) {
410; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp olt <2 x float> [[IN]], zeroinitializer
411; CHECK-NEXT:    [[SEL_NEW:%.*]] = select <2 x i1> [[CMP1_INV]], <2 x float> zeroinitializer, <2 x float> [[IN]]
412; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
413; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
414;
415  %cmp1 = fcmp uge <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
416  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
417  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
418  ret <2 x float> %sel
419}
420
421
422; fcmp ULT + fadd + sel => fcmp ULT + sel => fcmp OGE + sel
423
424define float @test_fcmp_ult_fadd_select_constant(float %in) {
425; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_constant(
426; CHECK-SAME: float [[IN:%.*]]) {
427; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp oge float [[IN]], 0.000000e+00
428; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
429; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
430; CHECK-NEXT:    ret float [[ADD_NEW]]
431;
432  %cmp1 = fcmp ult float %in, 0.000000e+00
433  %add = fadd float %in, 1.000000e+00
434  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
435  ret float %sel
436}
437
438define float @test_fcmp_ult_fadd_select_constant_swapped(float %in) {
439; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_constant_swapped(
440; CHECK-SAME: float [[IN:%.*]]) {
441; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp oge float [[IN]], 0.000000e+00
442; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float [[IN]], float 0.000000e+00
443; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
444; CHECK-NEXT:    ret float [[ADD_NEW]]
445;
446  %cmp1 = fcmp ult float %in, 0.000000e+00
447  %add = fadd float %in, 1.000000e+00
448  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
449  ret float %sel
450}
451
452define float @test_fcmp_ult_fadd_select_neg_constant(float %in) {
453; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_neg_constant(
454; CHECK-SAME: float [[IN:%.*]]) {
455; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp oge float [[IN]], 0.000000e+00
456; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
457; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
458; CHECK-NEXT:    ret float [[ADD_NEW]]
459;
460  %cmp1 = fcmp ult float %in, -0.000000e+00
461  %add = fadd float %in, 1.000000e+00
462  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
463  ret float %sel
464}
465
466define float @test_fcmp_ult_fadd_select_fastmath_preserve(float %in) {
467; CHECK-LABEL: define float @test_fcmp_ult_fadd_select_fastmath_preserve(
468; CHECK-SAME: float [[IN:%.*]]) {
469; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp oge float [[IN]], 0.000000e+00
470; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
471; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
472; CHECK-NEXT:    ret float [[ADD_NEW]]
473;
474  %cmp1 = fcmp ult float %in, 0.000000e+00
475  %add = fadd nnan float %in, 1.000000e+00
476  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
477  ret float %sel
478}
479
480define <2 x float> @test_fcmp_ult_fadd_select_constant_vectors(<2 x float> %in) {
481; CHECK-LABEL: define <2 x float> @test_fcmp_ult_fadd_select_constant_vectors(
482; CHECK-SAME: <2 x float> [[IN:%.*]]) {
483; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp oge <2 x float> [[IN]], zeroinitializer
484; CHECK-NEXT:    [[SEL_NEW:%.*]] = select <2 x i1> [[CMP1_INV]], <2 x float> zeroinitializer, <2 x float> [[IN]]
485; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
486; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
487;
488  %cmp1 = fcmp ult <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
489  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
490  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
491  ret <2 x float> %sel
492}
493
494
495; fcmp ULE + fadd + sel => fcmp ULE + sel => fcmp OGT + sel
496
497define float @test_fcmp_ule_fadd_select_constant(float %in) {
498; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_constant(
499; CHECK-SAME: float [[IN:%.*]]) {
500; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
501; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
502; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
503; CHECK-NEXT:    ret float [[ADD_NEW]]
504;
505  %cmp1 = fcmp ule float %in, 0.000000e+00
506  %add = fadd float %in, 1.000000e+00
507  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
508  ret float %sel
509}
510
511define float @test_fcmp_ule_fadd_select_constant_swapped(float %in) {
512; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_constant_swapped(
513; CHECK-SAME: float [[IN:%.*]]) {
514; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
515; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float [[IN]], float 0.000000e+00
516; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
517; CHECK-NEXT:    ret float [[ADD_NEW]]
518;
519  %cmp1 = fcmp ule float %in, 0.000000e+00
520  %add = fadd float %in, 1.000000e+00
521  %sel = select nnan nsz i1 %cmp1, float 1.000000e+00, float %add
522  ret float %sel
523}
524
525define float @test_fcmp_ule_fadd_select_neg_constant(float %in) {
526; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_neg_constant(
527; CHECK-SAME: float [[IN:%.*]]) {
528; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
529; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
530; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
531; CHECK-NEXT:    ret float [[ADD_NEW]]
532;
533  %cmp1 = fcmp ule float %in, -0.000000e+00
534  %add = fadd float %in, 1.000000e+00
535  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
536  ret float %sel
537}
538
539define float @test_fcmp_ule_fadd_select_fastmath_preserve(float %in) {
540; CHECK-LABEL: define float @test_fcmp_ule_fadd_select_fastmath_preserve(
541; CHECK-SAME: float [[IN:%.*]]) {
542; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
543; CHECK-NEXT:    [[SEL_NEW:%.*]] = select i1 [[CMP1_INV]], float 0.000000e+00, float [[IN]]
544; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
545; CHECK-NEXT:    ret float [[ADD_NEW]]
546;
547  %cmp1 = fcmp ule float %in, 0.000000e+00
548  %add = fadd nnan float %in, 1.000000e+00
549  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
550  ret float %sel
551}
552
553define <2 x float> @test_fcmp_ule_fadd_select_constant_vectors(<2 x float> %in) {
554; CHECK-LABEL: define <2 x float> @test_fcmp_ule_fadd_select_constant_vectors(
555; CHECK-SAME: <2 x float> [[IN:%.*]]) {
556; CHECK-NEXT:    [[CMP1_INV:%.*]] = fcmp ogt <2 x float> [[IN]], zeroinitializer
557; CHECK-NEXT:    [[SEL_NEW:%.*]] = select <2 x i1> [[CMP1_INV]], <2 x float> zeroinitializer, <2 x float> [[IN]]
558; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz <2 x float> [[SEL_NEW]], splat (float 1.000000e+00)
559; CHECK-NEXT:    ret <2 x float> [[ADD_NEW]]
560;
561  %cmp1 = fcmp ule <2 x float> %in, <float 0.000000e+00, float 0.000000e+00>
562  %add = fadd <2 x float> %in, <float 1.000000e+00, float 1.000000e+00>
563  %sel = select nnan nsz <2 x i1> %cmp1, <2 x float> %add, <2 x float> <float 1.000000e+00, float 1.000000e+00>
564  ret <2 x float> %sel
565}
566
567
568; Negative scenarios
569
570; select instruction doesn't give nnan and nsz guarantees.
571define float @test_select_without_nnan_nsz(float %in) {
572; CHECK-LABEL: define float @test_select_without_nnan_nsz(
573; CHECK-SAME: float [[IN:%.*]]) {
574; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
575; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
576; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], float [[ADD]], float 1.000000e+00
577; CHECK-NEXT:    ret float [[SEL]]
578;
579  %cmp1 = fcmp ogt float %in, 0.000000e+00
580  %add = fadd float %in, 1.000000e+00
581  %sel = select i1 %cmp1, float %add, float 1.000000e+00
582  ret float %sel
583}
584
585; fcmp arg doesn't match with fadd's. This won't be converted to maxnum/minnum.
586define float @test_fcmp_fadd_arg_mismatch(float %in, float %in2) {
587; CHECK-LABEL: define float @test_fcmp_fadd_arg_mismatch(
588; CHECK-SAME: float [[IN:%.*]], float [[IN2:%.*]]) {
589; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[IN2]], 0.000000e+00
590; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
591; CHECK-NEXT:    [[SEL:%.*]] = select nnan nsz i1 [[CMP1]], float [[ADD]], float 1.000000e+00
592; CHECK-NEXT:    ret float [[SEL]]
593;
594  %cmp1 = fcmp ogt float %in2, 0.000000e+00
595  %add = fadd float %in, 1.000000e+00
596  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
597  ret float %sel
598}
599
600; It won't be converted to maxnum/minnum because constant arg in fcmp isn't zero.
601define float @test_fcmp_arg_non_zero(float %in) {
602; CHECK-LABEL: define float @test_fcmp_arg_non_zero(
603; CHECK-SAME: float [[IN:%.*]]) {
604; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[IN]], 1.000000e+00
605; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
606; CHECK-NEXT:    [[SEL:%.*]] = select nnan nsz i1 [[CMP1]], float [[ADD]], float 1.000000e+00
607; CHECK-NEXT:    ret float [[SEL]]
608;
609  %cmp1 = fcmp ogt float %in, 1.000000e+00
610  %add = fadd float %in, 1.000000e+00
611  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
612  ret float %sel
613}
614
615; fcmp has more than one use.
616define float @test_fcmp_multiple_uses(float %in) {
617; CHECK-LABEL: define float @test_fcmp_multiple_uses(
618; CHECK-SAME: float [[IN:%.*]]) {
619; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[IN]], 0.000000e+00
620; CHECK-NEXT:    [[ADD:%.*]] = fadd float [[IN]], 1.000000e+00
621; CHECK-NEXT:    [[ADD_2:%.*]] = fadd float [[IN]], 1.000000e+00
622; CHECK-NEXT:    [[SEL_1:%.*]] = select nnan nsz i1 [[CMP1]], float [[ADD]], float 1.000000e+00
623; CHECK-NEXT:    [[SEL_2:%.*]] = select nnan nsz i1 [[CMP1]], float 2.000000e+00, float [[ADD_2]]
624; CHECK-NEXT:    [[RES:%.*]] = fadd float [[SEL_1]], [[SEL_2]]
625; CHECK-NEXT:    ret float [[RES]]
626;
627  %cmp1 = fcmp ogt float %in, 0.000000e+00
628  %add = fadd float %in, 1.000000e+00
629  %add.2 = fadd float %in, 1.000000e+00
630  %sel.1 = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
631  %sel.2 = select nnan nsz i1 %cmp1, float 2.000000e+00, float %add.2
632  %res = fadd float %sel.1, %sel.2
633  ret float %res
634}
635
636; Rewrite-based flags propagation
637define float @test_fcmp_ogt_fadd_select_rewrite_flags1(float %in) {
638; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_rewrite_flags1(
639; CHECK-SAME: float [[IN:%.*]]) {
640; CHECK-NEXT:    [[SEL_NEW:%.*]] = call reassoc nsz arcp contract afn float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
641; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd reassoc nnan nsz arcp contract afn float [[SEL_NEW]], 1.000000e+00
642; CHECK-NEXT:    ret float [[ADD_NEW]]
643;
644  %cmp1 = fcmp ogt float %in, 0.000000e+00
645  %add = fadd reassoc afn arcp contract float %in, 1.000000e+00
646  %sel = select nnan nsz reassoc afn arcp contract i1 %cmp1, float %add, float 1.000000e+00
647  ret float %sel
648}
649
650define float @test_fcmp_ogt_fadd_select_rewrite_flags2(float %in) {
651; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_rewrite_flags2(
652; CHECK-SAME: float [[IN:%.*]]) {
653; CHECK-NEXT:    [[SEL_NEW:%.*]] = call nsz float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
654; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd nnan nsz float [[SEL_NEW]], 1.000000e+00
655; CHECK-NEXT:    ret float [[ADD_NEW]]
656;
657  %cmp1 = fcmp ogt float %in, 0.000000e+00
658  %add = fadd reassoc float %in, 1.000000e+00
659  %sel = select nnan nsz i1 %cmp1, float %add, float 1.000000e+00
660  ret float %sel
661}
662
663define float @test_fcmp_ogt_fadd_select_rewrite_and_fastmath(float %in) {
664; CHECK-LABEL: define float @test_fcmp_ogt_fadd_select_rewrite_and_fastmath(
665; CHECK-SAME: float [[IN:%.*]]) {
666; CHECK-NEXT:    [[SEL_NEW:%.*]] = call fast float @llvm.maxnum.f32(float [[IN]], float 0.000000e+00)
667; CHECK-NEXT:    [[ADD_NEW:%.*]] = fadd fast float [[SEL_NEW]], 1.000000e+00
668; CHECK-NEXT:    ret float [[ADD_NEW]]
669;
670  %cmp1 = fcmp nnan ogt float %in, 0.000000e+00
671  %add = fadd fast reassoc float %in, 1.000000e+00
672  %sel = select fast i1 %cmp1, float %add, float 1.000000e+00
673  ret float %sel
674}
675