xref: /llvm-project/llvm/test/Transforms/InstCombine/minmax-fp.ll (revision de415fbb450d0e15c535f0ccc135e2368a15bf6f)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4; This is the canonical form for a type-changing min/max.
5define double @t1(float %a) {
6; CHECK-LABEL: @t1(
7; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 5.000000e+00
8; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float 5.000000e+00, float [[A]]
9; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[TMP1]] to double
10; CHECK-NEXT:    ret double [[TMP2]]
11;
12  %1 = fcmp ult float %a, 5.0
13  %2 = select i1 %1, float %a, float 5.0
14  %3 = fpext float %2 to double
15  ret double %3
16}
17
18; Check this is converted into canonical form, as above.
19define double @t2(float %a) {
20; CHECK-LABEL: @t2(
21; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 5.000000e+00
22; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float 5.000000e+00, float [[A]]
23; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[TMP1]] to double
24; CHECK-NEXT:    ret double [[TMP2]]
25;
26  %1 = fcmp ult float %a, 5.0
27  %2 = fpext float %a to double
28  %3 = select i1 %1, double %2, double 5.0
29  ret double %3
30}
31
32; Same again, with trunc.
33define float @t4(double %a) {
34; CHECK-LABEL: @t4(
35; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge double [[A:%.*]], 5.000000e+00
36; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], double 5.000000e+00, double [[A]]
37; CHECK-NEXT:    [[TMP2:%.*]] = fptrunc double [[TMP1]] to float
38; CHECK-NEXT:    ret float [[TMP2]]
39;
40  %1 = fcmp ult double %a, 5.0
41  %2 = fptrunc double %a to float
42  %3 = select i1 %1, float %2, float 5.0
43  ret float %3
44}
45
46; different values, should not be converted.
47define double @t5(float %a) {
48; CHECK-LABEL: @t5(
49; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult float [[A:%.*]], 5.000000e+00
50; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[A]] to double
51; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], double [[TMP2]], double 5.001000e+00
52; CHECK-NEXT:    ret double [[TMP3]]
53;
54  %1 = fcmp ult float %a, 5.0
55  %2 = fpext float %a to double
56  %3 = select i1 %1, double %2, double 5.001
57  ret double %3
58}
59
60; PR57357
61
62define float @not_maxnum(float %x) {
63; CHECK-LABEL: @not_maxnum(
64; CHECK-NEXT:    [[CMP:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
65; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], float -0.000000e+00, float [[X]]
66; CHECK-NEXT:    ret float [[SEL]]
67;
68  %cmp = fcmp olt float %x, 0.0
69  %sel = select i1 %cmp, float -0.0, float %x
70  ret float %sel
71}
72
73; From IEEE754: "Comparisons shall ignore the sign of zero (so +0 = -0)."
74; So the compare constant may be treated as +0.0, and we sink the fpext.
75
76define double @t6(float %a) {
77; CHECK-LABEL: @t6(
78; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
79; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
80; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[TMP1]] to double
81; CHECK-NEXT:    ret double [[TMP2]]
82;
83  %1 = fcmp ult float %a, -0.0
84  %2 = fpext float %a to double
85  %3 = select i1 %1, double %2, double 0.0
86  ret double %3
87}
88
89; TODO: Move the select ahead of the fpext because it's a narrower op.
90; This works as long as the wide constant can be represented exactly in the narrow type.
91
92define double @t7(float %a) {
93; CHECK-LABEL: @t7(
94; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult float [[A:%.*]], 0.000000e+00
95; CHECK-NEXT:    [[TMP2:%.*]] = fpext float [[A]] to double
96; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], double [[TMP2]], double -0.000000e+00
97; CHECK-NEXT:    ret double [[TMP3]]
98;
99  %1 = fcmp ult float %a, 0.0
100  %2 = fpext float %a to double
101  %3 = select i1 %1, double %2, double -0.0
102  ret double %3
103}
104
105; min(min(x, 0.0), 0.0) --> min(x, 0.0)
106
107define float @fmin_fmin_zero_mismatch(float %x) {
108; CHECK-LABEL: @fmin_fmin_zero_mismatch(
109; CHECK-NEXT:    [[CMP1:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
110; CHECK-NEXT:    [[MIN2:%.*]] = select i1 [[CMP1]], float [[X]], float 0.000000e+00
111; CHECK-NEXT:    ret float [[MIN2]]
112;
113  %cmp1 = fcmp olt float %x, -0.0
114  %min1 = select i1 %cmp1, float %x, float 0.0
115  %cmp2 = fcmp olt float %min1, 0.0
116  %min2 = select i1 %cmp2, float %min1, float 0.0
117  ret float %min2
118}
119
120; max(max(x, -0.0), -0.0) --> max(x, -0.0)
121define float @fmax_fmax_zero_mismatch(float %x) {
122; CHECK-LABEL: @fmax_fmax_zero_mismatch(
123; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ogt float [[X:%.*]], 0.000000e+00
124; CHECK-NEXT:    [[MAX1:%.*]] = select i1 [[CMP1]], float [[X]], float -0.000000e+00
125; CHECK-NEXT:    ret float [[MAX1]]
126;
127  %cmp1 = fcmp ogt float %x, 0.0
128  %max1 = select i1 %cmp1, float %x, float -0.0
129  %cmp2 = fcmp ogt float 0.0, %max1
130  %max2 = select i1 %cmp2, float -0.0, float %max1
131  ret float %max2
132}
133
134define i64 @t8(float %a) {
135; CHECK-LABEL: @t8(
136; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 5.000000e+00
137; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float 5.000000e+00, float [[A]]
138; CHECK-NEXT:    [[TMP2:%.*]] = fptoui float [[TMP1]] to i64
139; CHECK-NEXT:    ret i64 [[TMP2]]
140;
141  %1 = fcmp ult float %a, 5.0
142  %2 = fptoui float %a to i64
143  %3 = select i1 %1, i64 %2, i64 5
144  ret i64 %3
145}
146
147define i8 @t9(float %a) {
148; CHECK-LABEL: @t9(
149; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
150; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
151; CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
152; CHECK-NEXT:    ret i8 [[TMP2]]
153;
154  %1 = fcmp ult float %a, 0.0
155  %2 = fptosi float %a to i8
156  %3 = select i1 %1, i8 %2, i8 0
157  ret i8 %3
158}
159
160  ; Either operand could be NaN, but fast modifier applied.
161define i8 @t11(float %a, float %b) {
162; CHECK-LABEL: @t11(
163; CHECK-NEXT:    [[DOTV:%.*]] = call fast float @llvm.minnum.f32(float [[B:%.*]], float [[A:%.*]])
164; CHECK-NEXT:    [[TMP1:%.*]] = fptosi float [[DOTV]] to i8
165; CHECK-NEXT:    ret i8 [[TMP1]]
166;
167  %1 = fcmp fast ult float %b, %a
168  %2 = fptosi float %a to i8
169  %3 = fptosi float %b to i8
170  %4 = select i1 %1, i8 %3, i8 %2
171  ret i8 %4
172}
173
174; Either operand could be NaN, but nnan modifier applied.
175define i8 @t12(float %a, float %b) {
176; CHECK-LABEL: @t12(
177; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp nnan oge float [[B:%.*]], [[A:%.*]]
178; CHECK-NEXT:    [[DOTV:%.*]] = select nnan i1 [[DOTINV]], float [[A]], float [[B]]
179; CHECK-NEXT:    [[TMP1:%.*]] = fptosi float [[DOTV]] to i8
180; CHECK-NEXT:    ret i8 [[TMP1]]
181;
182  %1 = fcmp nnan ult float %b, %a
183  %2 = fptosi float %a to i8
184  %3 = fptosi float %b to i8
185  %4 = select i1 %1, i8 %3, i8 %2
186  ret i8 %4
187}
188
189; Float and int values do not match.
190define i8 @t13(float %a) {
191; CHECK-LABEL: @t13(
192; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult float [[A:%.*]], 1.500000e+00
193; CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[A]] to i8
194; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i8 [[TMP2]], i8 1
195; CHECK-NEXT:    ret i8 [[TMP3]]
196;
197  %1 = fcmp ult float %a, 1.5
198  %2 = fptosi float %a to i8
199  %3 = select i1 %1, i8 %2, i8 1
200  ret i8 %3
201}
202
203; %a could be -0.0, but it doesn't matter because the conversion to int is the same for 0.0 or -0.0.
204define i8 @t14(float %a) {
205; CHECK-LABEL: @t14(
206; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp oge float [[A:%.*]], 0.000000e+00
207; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[DOTINV]], float 0.000000e+00, float [[A]]
208; CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
209; CHECK-NEXT:    ret i8 [[TMP2]]
210;
211  %1 = fcmp ule float %a, 0.0
212  %2 = fptosi float %a to i8
213  %3 = select i1 %1, i8 %2, i8 0
214  ret i8 %3
215}
216
217define i8 @t14_commute(float %a) {
218; CHECK-LABEL: @t14_commute(
219; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ogt float [[A:%.*]], 0.000000e+00
220; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], float [[A]], float 0.000000e+00
221; CHECK-NEXT:    [[TMP3:%.*]] = fptosi float [[TMP2]] to i8
222; CHECK-NEXT:    ret i8 [[TMP3]]
223;
224  %1 = fcmp ule float %a, 0.0
225  %2 = fptosi float %a to i8
226  %3 = select i1 %1, i8 0, i8 %2
227  ret i8 %3
228}
229
230define i8 @t15(float %a) {
231; CHECK-LABEL: @t15(
232; CHECK-NEXT:    [[DOTINV:%.*]] = fcmp nsz oge float [[A:%.*]], 0.000000e+00
233; CHECK-NEXT:    [[TMP1:%.*]] = select nsz i1 [[DOTINV]], float 0.000000e+00, float [[A]]
234; CHECK-NEXT:    [[TMP2:%.*]] = fptosi float [[TMP1]] to i8
235; CHECK-NEXT:    ret i8 [[TMP2]]
236;
237  %1 = fcmp nsz ule float %a, 0.0
238  %2 = fptosi float %a to i8
239  %3 = select i1 %1, i8 %2, i8 0
240  ret i8 %3
241}
242
243define double @t16(i32 %x) {
244; CHECK-LABEL: @t16(
245; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], 0
246; CHECK-NEXT:    [[CST:%.*]] = sitofp i32 [[X]] to double
247; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP]], double [[CST]], double 5.000000e-01
248; CHECK-NEXT:    ret double [[SEL]]
249;
250  %cmp = icmp sgt i32 %x, 0
251  %cst = sitofp i32 %x to double
252  %sel = select i1 %cmp, double %cst, double 5.000000e-01
253  ret double %sel
254}
255
256define double @t17(i32 %x) {
257; CHECK-LABEL: @t17(
258; CHECK-NEXT:    [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 2)
259; CHECK-NEXT:    [[SEL:%.*]] = uitofp nneg i32 [[SEL1]] to double
260; CHECK-NEXT:    ret double [[SEL]]
261;
262  %cmp = icmp sgt i32 %x, 2
263  %cst = sitofp i32 %x to double
264  %sel = select i1 %cmp, double %cst, double 2.0
265  ret double %sel
266}
267
268define float @fneg_fmax(float %x, float %y) {
269; CHECK-LABEL: @fneg_fmax(
270; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan olt float [[X:%.*]], [[Y:%.*]]
271; CHECK-NEXT:    [[MAX_V:%.*]] = select i1 [[COND]], float [[X]], float [[Y]]
272; CHECK-NEXT:    [[MAX:%.*]] = fneg float [[MAX_V]]
273; CHECK-NEXT:    ret float [[MAX]]
274;
275  %n1 = fneg float %x
276  %n2 = fneg float %y
277  %cond = fcmp nnan ogt float %n1, %n2
278  %max = select i1 %cond, float %n1, float %n2
279  ret float %max
280}
281
282define <2 x float> @fsub_fmax(<2 x float> %x, <2 x float> %y) {
283; CHECK-LABEL: @fsub_fmax(
284; CHECK-NEXT:    [[MAX_V:%.*]] = call nnan nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[X:%.*]], <2 x float> [[Y:%.*]])
285; CHECK-NEXT:    [[MAX:%.*]] = fneg <2 x float> [[MAX_V]]
286; CHECK-NEXT:    ret <2 x float> [[MAX]]
287;
288  %n1 = fsub <2 x float> <float -0.0, float -0.0>, %x
289  %n2 = fsub <2 x float> <float -0.0, float -0.0>, %y
290  %cond = fcmp nsz nnan uge <2 x float> %n1, %n2
291  %max = select <2 x i1> %cond, <2 x float> %n1, <2 x float> %n2
292  ret <2 x float> %max
293}
294
295define <2 x double> @fsub_fmin(<2 x double> %x, <2 x double> %y) {
296; CHECK-LABEL: @fsub_fmin(
297; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan ogt <2 x double> [[X:%.*]], [[Y:%.*]]
298; CHECK-NEXT:    [[MAX_V:%.*]] = select <2 x i1> [[COND]], <2 x double> [[X]], <2 x double> [[Y]]
299; CHECK-NEXT:    [[MAX:%.*]] = fneg <2 x double> [[MAX_V]]
300; CHECK-NEXT:    ret <2 x double> [[MAX]]
301;
302  %n1 = fsub <2 x double> <double -0.0, double -0.0>, %x
303  %n2 = fsub <2 x double> <double -0.0, double -0.0>, %y
304  %cond = fcmp nnan olt <2 x double> %n1, %n2
305  %max = select <2 x i1> %cond, <2 x double> %n1, <2 x double> %n2
306  ret <2 x double> %max
307}
308
309define double @fneg_fmin(double %x, double %y) {
310; CHECK-LABEL: @fneg_fmin(
311; CHECK-NEXT:    [[MAX_V:%.*]] = call nnan nsz double @llvm.maxnum.f64(double [[X:%.*]], double [[Y:%.*]])
312; CHECK-NEXT:    [[MAX:%.*]] = fneg double [[MAX_V]]
313; CHECK-NEXT:    ret double [[MAX]]
314;
315  %n1 = fneg double %x
316  %n2 = fneg double %y
317  %cond = fcmp nsz nnan ule double %n1, %n2
318  %max = select i1 %cond, double %n1, double %n2
319  ret double %max
320}
321
322define float @maxnum_ogt_fmf_on_select(float %a, float %b) {
323; CHECK-LABEL: @maxnum_ogt_fmf_on_select(
324; CHECK-NEXT:    [[F:%.*]] = call nsz float @llvm.maxnum.f32(float [[A:%.*]], float [[B:%.*]])
325; CHECK-NEXT:    ret float [[F]]
326;
327  %cond = fcmp ogt float %a, %b
328  %f = select nnan nsz i1 %cond, float %a, float %b
329  ret float %f
330}
331
332define <2 x float> @maxnum_oge_fmf_on_select(<2 x float> %a, <2 x float> %b) {
333; CHECK-LABEL: @maxnum_oge_fmf_on_select(
334; CHECK-NEXT:    [[F:%.*]] = call ninf nsz <2 x float> @llvm.maxnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
335; CHECK-NEXT:    ret <2 x float> [[F]]
336;
337  %cond = fcmp oge <2 x float> %a, %b
338  %f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
339  ret <2 x float> %f
340}
341
342define float @maxnum_ogt_fmf_on_fcmp(float %a, float %b) {
343; CHECK-LABEL: @maxnum_ogt_fmf_on_fcmp(
344; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan nsz ogt float [[A:%.*]], [[B:%.*]]
345; CHECK-NEXT:    [[F:%.*]] = select i1 [[COND]], float [[A]], float [[B]]
346; CHECK-NEXT:    ret float [[F]]
347;
348  %cond = fcmp nnan nsz ogt float %a, %b
349  %f = select i1 %cond, float %a, float %b
350  ret float %f
351}
352
353define <2 x float> @maxnum_oge_fmf_on_fcmp(<2 x float> %a, <2 x float> %b) {
354; CHECK-LABEL: @maxnum_oge_fmf_on_fcmp(
355; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan ninf nsz oge <2 x float> [[A:%.*]], [[B:%.*]]
356; CHECK-NEXT:    [[F:%.*]] = select <2 x i1> [[COND]], <2 x float> [[A]], <2 x float> [[B]]
357; CHECK-NEXT:    ret <2 x float> [[F]]
358;
359  %cond = fcmp ninf nnan nsz oge <2 x float> %a, %b
360  %f = select <2 x i1> %cond, <2 x float> %a, <2 x float> %b
361  ret <2 x float> %f
362}
363
364define float @maxnum_no_nsz(float %a, float %b) {
365; CHECK-LABEL: @maxnum_no_nsz(
366; CHECK-NEXT:    [[COND:%.*]] = fcmp ogt float [[A:%.*]], [[B:%.*]]
367; CHECK-NEXT:    [[F:%.*]] = select nnan i1 [[COND]], float [[A]], float [[B]]
368; CHECK-NEXT:    ret float [[F]]
369;
370  %cond = fcmp ogt float %a, %b
371  %f = select nnan i1 %cond, float %a, float %b
372  ret float %f
373}
374
375define float @maxnum_no_nnan(float %a, float %b) {
376; CHECK-LABEL: @maxnum_no_nnan(
377; CHECK-NEXT:    [[COND:%.*]] = fcmp oge float [[A:%.*]], [[B:%.*]]
378; CHECK-NEXT:    [[F:%.*]] = select nsz i1 [[COND]], float [[A]], float [[B]]
379; CHECK-NEXT:    ret float [[F]]
380;
381  %cond = fcmp oge float %a, %b
382  %f = select nsz i1 %cond, float %a, float %b
383  ret float %f
384}
385
386define float @minnum_olt_fmf_on_select(float %a, float %b) {
387; CHECK-LABEL: @minnum_olt_fmf_on_select(
388; CHECK-NEXT:    [[F:%.*]] = call nsz float @llvm.minnum.f32(float [[A:%.*]], float [[B:%.*]])
389; CHECK-NEXT:    ret float [[F]]
390;
391  %cond = fcmp olt float %a, %b
392  %f = select nnan nsz i1 %cond, float %a, float %b
393  ret float %f
394}
395
396define <2 x float> @minnum_ole_fmf_on_select(<2 x float> %a, <2 x float> %b) {
397; CHECK-LABEL: @minnum_ole_fmf_on_select(
398; CHECK-NEXT:    [[F:%.*]] = call ninf nsz <2 x float> @llvm.minnum.v2f32(<2 x float> [[A:%.*]], <2 x float> [[B:%.*]])
399; CHECK-NEXT:    ret <2 x float> [[F]]
400;
401  %cond = fcmp ole <2 x float> %a, %b
402  %f = select ninf nnan nsz <2 x i1> %cond, <2 x float> %a, <2 x float> %b
403  ret <2 x float> %f
404}
405
406define float @minnum_olt_fmf_on_fcmp(float %a, float %b) {
407; CHECK-LABEL: @minnum_olt_fmf_on_fcmp(
408; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan nsz olt float [[A:%.*]], [[B:%.*]]
409; CHECK-NEXT:    [[F:%.*]] = select i1 [[COND]], float [[A]], float [[B]]
410; CHECK-NEXT:    ret float [[F]]
411;
412  %cond = fcmp nnan nsz olt float %a, %b
413  %f = select i1 %cond, float %a, float %b
414  ret float %f
415}
416
417define <2 x float> @minnum_ole_fmf_on_fcmp(<2 x float> %a, <2 x float> %b) {
418; CHECK-LABEL: @minnum_ole_fmf_on_fcmp(
419; CHECK-NEXT:    [[COND:%.*]] = fcmp nnan ninf nsz ole <2 x float> [[A:%.*]], [[B:%.*]]
420; CHECK-NEXT:    [[F:%.*]] = select <2 x i1> [[COND]], <2 x float> [[A]], <2 x float> [[B]]
421; CHECK-NEXT:    ret <2 x float> [[F]]
422;
423  %cond = fcmp ninf nnan nsz ole <2 x float> %a, %b
424  %f = select <2 x i1> %cond, <2 x float> %a, <2 x float> %b
425  ret <2 x float> %f
426}
427
428define float @minnum_no_nsz(float %a, float %b) {
429; CHECK-LABEL: @minnum_no_nsz(
430; CHECK-NEXT:    [[COND:%.*]] = fcmp olt float [[A:%.*]], [[B:%.*]]
431; CHECK-NEXT:    [[F:%.*]] = select nnan i1 [[COND]], float [[A]], float [[B]]
432; CHECK-NEXT:    ret float [[F]]
433;
434  %cond = fcmp olt float %a, %b
435  %f = select nnan i1 %cond, float %a, float %b
436  ret float %f
437}
438
439define float @minnum_no_nnan(float %a, float %b) {
440; CHECK-LABEL: @minnum_no_nnan(
441; CHECK-NEXT:    [[COND:%.*]] = fcmp ole float [[A:%.*]], [[B:%.*]]
442; CHECK-NEXT:    [[F:%.*]] = select nsz i1 [[COND]], float [[A]], float [[B]]
443; CHECK-NEXT:    ret float [[F]]
444;
445  %cond = fcmp ole float %a, %b
446  %f = select nsz i1 %cond, float %a, float %b
447  ret float %f
448}
449
450define float @pr64937_preserve_min_idiom(float %a) {
451; CHECK-LABEL: @pr64937_preserve_min_idiom(
452; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan olt float [[A:%.*]], 3.276700e+04
453; CHECK-NEXT:    [[SEL:%.*]] = select nnan i1 [[CMP]], float [[A]], float 3.276700e+04
454; CHECK-NEXT:    [[RES:%.*]] = fmul nnan float [[SEL]], 6.553600e+04
455; CHECK-NEXT:    ret float [[RES]]
456;
457  %cmp = fcmp nnan olt float %a, 3.276700e+04
458  %sel = select nnan i1 %cmp, float %a, float 3.276700e+04
459  %res = fmul nnan float %sel, 6.553600e+04
460  ret float %res
461}
462