@@ -259,3 +259,170 @@ define <2 x i1> @uno8(<2 x double> %x, <2 x double> %y) {
259
259
%r = or <2 x i1 > %cmp1 , %cmp2
260
260
ret <2 x i1 > %r
261
261
}
262
+
263
+ define 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
+
274
+ define 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
+
285
+ define 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
+
296
+ define 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
+
307
+ define <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
+
318
+ define 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
+
329
+ define 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
+
339
+ define 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
+
350
+ define 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
+
361
+ define 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
372
+ define 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
+
391
+ define 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
+
404
+ define 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
+
417
+ define 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
+ }
0 commit comments