xref: /llvm-project/llvm/test/Transforms/InstSimplify/logic-of-fcmps.ll (revision 42ed7757835122a63477b5783215e1100cd0b709)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3
4; Cycle through commuted variants where one operand of fcmp ord/uno is
5; known not-a-NAN and the other is repeated in the logically-connected fcmp.
6
7declare float @llvm.fabs.f32(float)
8declare void @llvm.assume(i1 noundef)
9
10define i1 @ord1(float %x, float %y) {
11; CHECK-LABEL: @ord1(
12; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
13; CHECK-NEXT:    ret i1 [[CMP2]]
14;
15  %cmp1 = fcmp ord float 0.0, %x
16  %cmp2 = fcmp ord float %x, %y
17  %r = and i1 %cmp1, %cmp2
18  ret i1 %r
19}
20
21define i1 @ord1_assume(float %x, float %y, float %not.nan) {
22; CHECK-LABEL: @ord1_assume(
23; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[NOT_NAN:%.*]], 0.000000e+00
24; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
25; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
26; CHECK-NEXT:    ret i1 [[CMP2]]
27;
28  %ord = fcmp ord float %not.nan, 0.0
29  call void @llvm.assume(i1 %ord)
30  %cmp1 = fcmp ord float %not.nan, %x
31  %cmp2 = fcmp ord float %x, %y
32  %r = and i1 %cmp1, %cmp2
33  ret i1 %r
34}
35
36define i1 @ord2(double %x, double %y) {
37; CHECK-LABEL: @ord2(
38; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord double [[Y:%.*]], [[X:%.*]]
39; CHECK-NEXT:    ret i1 [[CMP2]]
40;
41  %cmp1 = fcmp ord double 42.0, %x
42  %cmp2 = fcmp ord double %y, %x
43  %r = and i1 %cmp1, %cmp2
44  ret i1 %r
45}
46
47define <2 x i1> @ord3(<2 x float> %x, <2 x float> %y) {
48; CHECK-LABEL: @ord3(
49; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord <2 x float> [[X:%.*]], [[Y:%.*]]
50; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
51;
52  %cmp1 = fcmp ord <2 x float> %x, zeroinitializer
53  %cmp2 = fcmp ord <2 x float> %x, %y
54  %r = and <2 x i1> %cmp1, %cmp2
55  ret <2 x i1> %r
56}
57
58define i1 @ord3_assume(float %x, float %y, float %not.nan) {
59; CHECK-LABEL: @ord3_assume(
60; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[NOT_NAN:%.*]], 0.000000e+00
61; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
62; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
63; CHECK-NEXT:    ret i1 [[CMP2]]
64;
65  %ord = fcmp ord float %not.nan, 0.0
66  call void @llvm.assume(i1 %ord)
67  %cmp1 = fcmp ord float %x, %not.nan
68  %cmp2 = fcmp ord float %x, %y
69  %r = and i1 %cmp1, %cmp2
70  ret i1 %r
71}
72
73define <2 x i1> @ord4(<2 x double> %x, <2 x double> %y) {
74; CHECK-LABEL: @ord4(
75; CHECK-NEXT:    [[CMP2:%.*]] = fcmp ord <2 x double> [[Y:%.*]], [[X:%.*]]
76; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
77;
78  %cmp1 = fcmp ord <2 x double> %x, <double 42.0, double 42.0>
79  %cmp2 = fcmp ord <2 x double> %y, %x
80  %r = and <2 x i1> %cmp1, %cmp2
81  ret <2 x i1> %r
82}
83
84define i1 @ord5(float %x, float %y) {
85; CHECK-LABEL: @ord5(
86; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
87; CHECK-NEXT:    ret i1 [[CMP1]]
88;
89  %nnan = fdiv nnan float %x, %y
90  %cmp1 = fcmp ord float %x, %y
91  %cmp2 = fcmp ord float %nnan, %x
92  %r = and i1 %cmp1, %cmp2
93  ret i1 %r
94}
95
96define i1 @ord5_assume(float %x, float %y, float %nnan) {
97; CHECK-LABEL: @ord5_assume(
98; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[NNAN:%.*]], 0.000000e+00
99; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
100; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
101; CHECK-NEXT:    ret i1 [[CMP1]]
102;
103  %ord = fcmp ord float %nnan, 0.0
104  call void @llvm.assume(i1 %ord)
105  %cmp1 = fcmp ord float %x, %y
106  %cmp2 = fcmp ord float %nnan, %x
107  %r = and i1 %cmp1, %cmp2
108  ret i1 %r
109}
110
111define i1 @ord6(double %x, double %y) {
112; CHECK-LABEL: @ord6(
113; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord double [[Y:%.*]], [[X:%.*]]
114; CHECK-NEXT:    ret i1 [[CMP1]]
115;
116  %cmp1 = fcmp ord double %y, %x
117  %cmp2 = fcmp ord double 42.0, %x
118  %r = and i1 %cmp1, %cmp2
119  ret i1 %r
120}
121
122define i1 @ord6_assume(double %x, double %y, double %not.nan) {
123; CHECK-LABEL: @ord6_assume(
124; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord double [[NOT_NAN:%.*]], 0.000000e+00
125; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
126; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord double [[Y:%.*]], [[X:%.*]]
127; CHECK-NEXT:    ret i1 [[CMP1]]
128;
129  %ord = fcmp ord double %not.nan, 0.0
130  call void @llvm.assume(i1 %ord)
131  %cmp1 = fcmp ord double %y, %x
132  %cmp2 = fcmp ord double %not.nan, %x
133  %r = and i1 %cmp1, %cmp2
134  ret i1 %r
135}
136
137define <2 x i1> @ord7(<2 x float> %x, <2 x float> %y) {
138; CHECK-LABEL: @ord7(
139; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord <2 x float> [[X:%.*]], [[Y:%.*]]
140; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
141;
142  %cmp1 = fcmp ord <2 x float> %x, %y
143  %cmp2 = fcmp ord <2 x float> %x, zeroinitializer
144  %r = and <2 x i1> %cmp1, %cmp2
145  ret <2 x i1> %r
146}
147
148define i1 @ord7_assume(float %x, float %y, float %not.nan) {
149; CHECK-LABEL: @ord7_assume(
150; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[NOT_NAN:%.*]], 0.000000e+00
151; CHECK-NEXT:    call void @llvm.assume(i1 [[ORD]])
152; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
153; CHECK-NEXT:    ret i1 [[CMP1]]
154;
155  %ord = fcmp ord float %not.nan, 0.0
156  call void @llvm.assume(i1 %ord)
157  %cmp1 = fcmp ord float %x, %y
158  %cmp2 = fcmp ord float %x, %not.nan
159  %r = and i1 %cmp1, %cmp2
160  ret i1 %r
161}
162
163define <2 x i1> @ord8(<2 x double> %x, <2 x double> %y) {
164; CHECK-LABEL: @ord8(
165; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord <2 x double> [[Y:%.*]], [[X:%.*]]
166; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
167;
168  %cmp1 = fcmp ord <2 x double> %y, %x
169  %cmp2 = fcmp ord <2 x double> %x, <double 0.0, double 42.0>
170  %r = and <2 x i1> %cmp1, %cmp2
171  ret <2 x i1> %r
172}
173
174define i1 @uno1(float %x, float %y) {
175; CHECK-LABEL: @uno1(
176; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
177; CHECK-NEXT:    ret i1 [[CMP2]]
178;
179  %cmp1 = fcmp uno float 0.0, %x
180  %cmp2 = fcmp uno float %x, %y
181  %r = or i1 %cmp1, %cmp2
182  ret i1 %r
183}
184
185define i1 @uno2(double %x, double %y) {
186; CHECK-LABEL: @uno2(
187; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno double [[Y:%.*]], [[X:%.*]]
188; CHECK-NEXT:    ret i1 [[CMP2]]
189;
190  %cmp1 = fcmp uno double 42.0, %x
191  %cmp2 = fcmp uno double %y, %x
192  %r = or i1 %cmp1, %cmp2
193  ret i1 %r
194}
195
196define <2 x i1> @uno3(<2 x float> %x, <2 x float> %y) {
197; CHECK-LABEL: @uno3(
198; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno <2 x float> [[X:%.*]], [[Y:%.*]]
199; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
200;
201  %cmp1 = fcmp uno <2 x float> %x, zeroinitializer
202  %cmp2 = fcmp uno <2 x float> %x, %y
203  %r = or <2 x i1> %cmp1, %cmp2
204  ret <2 x i1> %r
205}
206
207define <2 x i1> @uno4(<2 x double> %x, <2 x double> %y) {
208; CHECK-LABEL: @uno4(
209; CHECK-NEXT:    [[CMP2:%.*]] = fcmp uno <2 x double> [[Y:%.*]], [[X:%.*]]
210; CHECK-NEXT:    ret <2 x i1> [[CMP2]]
211;
212  %cmp1 = fcmp uno <2 x double> %x, <double 42.0, double 42.0>
213  %cmp2 = fcmp uno <2 x double> %y, %x
214  %r = or <2 x i1> %cmp1, %cmp2
215  ret <2 x i1> %r
216}
217
218define i1 @uno5(float %x, float %y) {
219; CHECK-LABEL: @uno5(
220; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
221; CHECK-NEXT:    ret i1 [[CMP1]]
222;
223  %cmp1 = fcmp uno float %x, %y
224  %cmp2 = fcmp uno float 0.0, %x
225  %r = or i1 %cmp1, %cmp2
226  ret i1 %r
227}
228
229define i1 @uno6(double %x, double %y) {
230; CHECK-LABEL: @uno6(
231; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno double [[Y:%.*]], [[X:%.*]]
232; CHECK-NEXT:    ret i1 [[CMP1]]
233;
234  %cmp1 = fcmp uno double %y, %x
235  %cmp2 = fcmp uno double 42.0, %x
236  %r = or i1 %cmp1, %cmp2
237  ret i1 %r
238}
239
240define <2 x i1> @uno7(<2 x float> %x, <2 x float> %y) {
241; CHECK-LABEL: @uno7(
242; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno <2 x float> [[X:%.*]], [[Y:%.*]]
243; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
244;
245  %nnan = fdiv nnan <2 x float> %x, %y
246  %cmp1 = fcmp uno <2 x float> %x, %y
247  %cmp2 = fcmp uno <2 x float> %x, %nnan
248  %r = or <2 x i1> %cmp1, %cmp2
249  ret <2 x i1> %r
250}
251
252define <2 x i1> @uno8(<2 x double> %x, <2 x double> %y) {
253; CHECK-LABEL: @uno8(
254; CHECK-NEXT:    [[CMP1:%.*]] = fcmp uno <2 x double> [[Y:%.*]], [[X:%.*]]
255; CHECK-NEXT:    ret <2 x i1> [[CMP1]]
256;
257  %cmp1 = fcmp uno <2 x double> %y, %x
258  %cmp2 = fcmp uno <2 x double> %x, <double 0x7ff0000000000000, double 42.0>
259  %r = or <2 x i1> %cmp1, %cmp2
260  ret <2 x i1> %r
261}
262
263define i1 @olt_implies_ord(float %x, float %y) {
264; CHECK-LABEL: @olt_implies_ord(
265; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
266; CHECK-NEXT:    ret i1 [[OLT]]
267;
268  %ord = fcmp ord float %x, 0.000000e+00
269  %olt = fcmp olt float %x, %y
270  %ret = and i1 %olt, %ord
271  ret i1 %ret
272}
273
274define i1 @olt_implies_ord_commuted1(float %x, float %y) {
275; CHECK-LABEL: @olt_implies_ord_commuted1(
276; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X:%.*]]
277; CHECK-NEXT:    ret i1 [[OLT]]
278;
279  %ord = fcmp ord float %x, 0.000000e+00
280  %olt = fcmp olt float %y, %x
281  %ret = and i1 %olt, %ord
282  ret i1 %ret
283}
284
285define i1 @olt_implies_ord_commuted2(float %x, float %y) {
286; CHECK-LABEL: @olt_implies_ord_commuted2(
287; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X:%.*]], [[Y:%.*]]
288; CHECK-NEXT:    ret i1 [[OLT]]
289;
290  %ord = fcmp ord float %x, 0.000000e+00
291  %olt = fcmp olt float %x, %y
292  %ret = and i1 %ord, %olt
293  ret i1 %ret
294}
295
296define i1 @olt_implies_ord_commuted3(float %x, float %y) {
297; CHECK-LABEL: @olt_implies_ord_commuted3(
298; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[Y:%.*]], [[X:%.*]]
299; CHECK-NEXT:    ret i1 [[OLT]]
300;
301  %ord = fcmp ord float %x, 0.000000e+00
302  %olt = fcmp olt float %y, %x
303  %ret = and i1 %ord, %olt
304  ret i1 %ret
305}
306
307define <2 x i1> @olt_implies_ord_vec(<2 x float> %x, <2 x float> %y) {
308; CHECK-LABEL: @olt_implies_ord_vec(
309; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt <2 x float> [[X:%.*]], [[Y:%.*]]
310; CHECK-NEXT:    ret <2 x i1> [[OLT]]
311;
312  %ord = fcmp ord <2 x float> %x, zeroinitializer
313  %olt = fcmp olt <2 x float> %x, %y
314  %ret = and <2 x i1> %ord, %olt
315  ret <2 x i1> %ret
316}
317
318define i1 @ord_implies_ord(float %x, float %y) {
319; CHECK-LABEL: @ord_implies_ord(
320; CHECK-NEXT:    [[ORD2:%.*]] = fcmp ord float [[X:%.*]], [[Y:%.*]]
321; CHECK-NEXT:    ret i1 [[ORD2]]
322;
323  %ord = fcmp ord float %x, 0.000000e+00
324  %ord2 = fcmp ord float %x, %y
325  %ret = and i1 %ord, %ord2
326  ret i1 %ret
327}
328
329define i1 @olt_implies_uno(float %x, float %y) {
330; CHECK-LABEL: @olt_implies_uno(
331; CHECK-NEXT:    ret i1 false
332;
333  %uno = fcmp uno float %x, 0.000000e+00
334  %olt = fcmp olt float %x, %y
335  %ret = and i1 %olt, %uno
336  ret i1 %ret
337}
338
339define i1 @ult_implies_uno(float %x, float %y) {
340; CHECK-LABEL: @ult_implies_uno(
341; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X:%.*]], [[Y:%.*]]
342; CHECK-NEXT:    ret i1 [[ULT]]
343;
344  %uno = fcmp uno float %x, 0.000000e+00
345  %ult = fcmp ult float %x, %y
346  %ret = or i1 %ult, %uno
347  ret i1 %ret
348}
349
350define i1 @uno_implies_uno(float %x, float %y) {
351; CHECK-LABEL: @uno_implies_uno(
352; CHECK-NEXT:    [[UNO2:%.*]] = fcmp uno float [[X:%.*]], [[Y:%.*]]
353; CHECK-NEXT:    ret i1 [[UNO2]]
354;
355  %uno = fcmp uno float %x, 0.000000e+00
356  %uno2 = fcmp uno float %x, %y
357  %ret = or i1 %uno, %uno2
358  ret i1 %ret
359}
360
361define i1 @ult_implies_ord(float %x, float %y) {
362; CHECK-LABEL: @ult_implies_ord(
363; CHECK-NEXT:    ret i1 true
364;
365  %ord = fcmp ord float %x, 0.000000e+00
366  %ult = fcmp ult float %x, %y
367  %ret = or i1 %ult, %ord
368  ret i1 %ret
369}
370
371; TODO: %cmp1 is false implies %cmp3 is true
372define float @test_ord_implies_uno(float %x) {
373; CHECK-LABEL: @test_ord_implies_uno(
374; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
375; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[X]], 0.000000e+00
376; CHECK-NEXT:    [[CMP3:%.*]] = fcmp uno float [[X]], 0.000000e+00
377; CHECK-NEXT:    [[SEL:%.*]] = select i1 [[CMP1]], i1 [[CMP2]], i1 [[CMP3]]
378; CHECK-NEXT:    [[RET:%.*]] = select i1 [[SEL]], float 0.000000e+00, float [[X]]
379; CHECK-NEXT:    ret float [[RET]]
380;
381  %cmp1 = fcmp ord float %x, 0.000000e+00
382  %cmp2 = fcmp olt float %x, 0.000000e+00
383  %cmp3 = fcmp uno float %x, 0.000000e+00
384  %sel = select i1 %cmp1, i1 %cmp2, i1 %cmp3
385  %ret = select i1 %sel, float 0.000000e+00, float %x
386  ret float %ret
387}
388
389; Negative tests
390
391define i1 @olt_implies_ord_fail(float %x, float %y, float %z) {
392; CHECK-LABEL: @olt_implies_ord_fail(
393; CHECK-NEXT:    [[ORD:%.*]] = fcmp ord float [[X:%.*]], [[Z:%.*]]
394; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
395; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[ORD]]
396; CHECK-NEXT:    ret i1 [[RET]]
397;
398  %ord = fcmp ord float %x, %z
399  %olt = fcmp olt float %x, %y
400  %ret = and i1 %olt, %ord
401  ret i1 %ret
402}
403
404define i1 @ult_implies_uno_and(float %x, float %y) {
405; CHECK-LABEL: @ult_implies_uno_and(
406; CHECK-NEXT:    [[UNO:%.*]] = fcmp uno float [[X:%.*]], 0.000000e+00
407; CHECK-NEXT:    [[ULT:%.*]] = fcmp ult float [[X]], [[Y:%.*]]
408; CHECK-NEXT:    [[RET:%.*]] = and i1 [[ULT]], [[UNO]]
409; CHECK-NEXT:    ret i1 [[RET]]
410;
411  %uno = fcmp uno float %x, 0.000000e+00
412  %ult = fcmp ult float %x, %y
413  %ret = and i1 %ult, %uno
414  ret i1 %ret
415}
416
417define i1 @olt_implies_olt_fail(float %x, float %y) {
418; CHECK-LABEL: @olt_implies_olt_fail(
419; CHECK-NEXT:    [[OLT:%.*]] = fcmp olt float [[X:%.*]], 0.000000e+00
420; CHECK-NEXT:    [[OLT2:%.*]] = fcmp olt float [[X]], [[Y:%.*]]
421; CHECK-NEXT:    [[RET:%.*]] = and i1 [[OLT]], [[OLT2]]
422; CHECK-NEXT:    ret i1 [[RET]]
423;
424  %olt = fcmp olt float %x, 0.000000e+00
425  %olt2 = fcmp olt float %x, %y
426  %ret = and i1 %olt, %olt2
427  ret i1 %ret
428}
429
430define i1 @and_ord_olt_abs(float %x, float %y) {
431; CHECK-LABEL: @and_ord_olt_abs(
432; CHECK-NEXT:    [[ABSX:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
433; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[ABSX]], [[Y:%.*]]
434; CHECK-NEXT:    ret i1 [[CMP2]]
435;
436  %cmp1 = fcmp ord float %x, 0.000000e+00
437  %absx = call float @llvm.fabs.f32(float %x)
438  %cmp2 = fcmp olt float %absx, %y
439  %and = and i1 %cmp1, %cmp2
440  ret i1 %and
441}
442
443define i1 @and_ord_olt_abs_commuted1(float %x, float %y) {
444; CHECK-LABEL: @and_ord_olt_abs_commuted1(
445; CHECK-NEXT:    [[ABSX:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
446; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[Y:%.*]], [[ABSX]]
447; CHECK-NEXT:    ret i1 [[CMP2]]
448;
449  %cmp1 = fcmp ord float %x, 0.000000e+00
450  %absx = call float @llvm.fabs.f32(float %x)
451  %cmp2 = fcmp olt float %y, %absx
452  %and = and i1 %cmp1, %cmp2
453  ret i1 %and
454}
455
456define i1 @and_ord_olt_abs_commuted2(float %x, float %y) {
457; CHECK-LABEL: @and_ord_olt_abs_commuted2(
458; CHECK-NEXT:    [[ABSX:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
459; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[ABSX]], [[Y:%.*]]
460; CHECK-NEXT:    ret i1 [[CMP2]]
461;
462  %cmp1 = fcmp ord float %x, 0.000000e+00
463  %absx = call float @llvm.fabs.f32(float %x)
464  %cmp2 = fcmp olt float %absx, %y
465  %and = and i1 %cmp2, %cmp1
466  ret i1 %and
467}
468
469define i1 @or_ord_ult_abs(float %x, float %y) {
470; CHECK-LABEL: @or_ord_ult_abs(
471; CHECK-NEXT:    ret i1 true
472;
473  %cmp1 = fcmp ord float %x, 0.000000e+00
474  %absx = call float @llvm.fabs.f32(float %x)
475  %cmp2 = fcmp ult float %absx, %y
476  %or = or i1 %cmp1, %cmp2
477  ret i1 %or
478}
479
480define i1 @and_ord_olt_absz(float %x, float %y, float %z) {
481; CHECK-LABEL: @and_ord_olt_absz(
482; CHECK-NEXT:    [[CMP1:%.*]] = fcmp ord float [[X:%.*]], 0.000000e+00
483; CHECK-NEXT:    [[ABSZ:%.*]] = call float @llvm.fabs.f32(float [[Z:%.*]])
484; CHECK-NEXT:    [[CMP2:%.*]] = fcmp olt float [[ABSZ]], [[Y:%.*]]
485; CHECK-NEXT:    [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]]
486; CHECK-NEXT:    ret i1 [[AND]]
487;
488  %cmp1 = fcmp ord float %x, 0.000000e+00
489  %absz = call float @llvm.fabs.f32(float %z)
490  %cmp2 = fcmp olt float %absz, %y
491  %and = and i1 %cmp1, %cmp2
492  ret i1 %and
493}
494