@@ -1374,5 +1374,185 @@ define i8 @nonzero_reduce_xor_vscale_odd(<vscale x 3 x i8> %xx) {
1374
1374
ret i8 %r
1375
1375
}
1376
1376
1377
+ define i1 @test_sign_pos (float %x ) {
1378
+ ; CHECK-LABEL: @test_sign_pos(
1379
+ ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1380
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FABS]] to i32
1381
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp sgt i32 [[Y]], -1
1382
+ ; CHECK-NEXT: ret i1 [[SIGN]]
1383
+ ;
1384
+ %fabs = call float @llvm.fabs.f32 (float %x )
1385
+ %y = bitcast float %fabs to i32
1386
+ %sign = icmp sgt i32 %y , -1
1387
+ ret i1 %sign
1388
+ }
1389
+
1390
+ define i1 @test_sign_neg (float %x ) {
1391
+ ; CHECK-LABEL: @test_sign_neg(
1392
+ ; CHECK-NEXT: [[FABS:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1393
+ ; CHECK-NEXT: [[FNABS:%.*]] = fneg float [[FABS]]
1394
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[FNABS]] to i32
1395
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp slt i32 [[Y]], 0
1396
+ ; CHECK-NEXT: ret i1 [[SIGN]]
1397
+ ;
1398
+ %fabs = call float @llvm.fabs.f32 (float %x )
1399
+ %fnabs = fneg float %fabs
1400
+ %y = bitcast float %fnabs to i32
1401
+ %sign = icmp slt i32 %y , 0
1402
+ ret i1 %sign
1403
+ }
1404
+
1405
+ define <2 x i1 > @test_sign_pos_vec (<2 x float > %x ) {
1406
+ ; CHECK-LABEL: @test_sign_pos_vec(
1407
+ ; CHECK-NEXT: [[FABS:%.*]] = call <2 x float> @llvm.fabs.v2f32(<2 x float> [[X:%.*]])
1408
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast <2 x float> [[FABS]] to <2 x i32>
1409
+ ; CHECK-NEXT: [[SIGN:%.*]] = icmp slt <2 x i32> [[Y]], zeroinitializer
1410
+ ; CHECK-NEXT: ret <2 x i1> [[SIGN]]
1411
+ ;
1412
+ %fabs = call <2 x float > @llvm.fabs.v2f32 (<2 x float > %x )
1413
+ %y = bitcast <2 x float > %fabs to <2 x i32 >
1414
+ %sign = icmp slt <2 x i32 > %y , zeroinitializer
1415
+ ret <2 x i1 > %sign
1416
+ }
1417
+
1418
+ define i32 @test_inf_only (float nofpclass(nan sub norm zero) %x ) {
1419
+ ; CHECK-LABEL: @test_inf_only(
1420
+ ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1421
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
1422
+ ; CHECK-NEXT: ret i32 [[AND]]
1423
+ ;
1424
+ %y = bitcast float %x to i32
1425
+ %and = and i32 %y , 2147483647
1426
+ ret i32 %and
1427
+ }
1428
+
1429
+ define i32 @test_zero_only (float nofpclass(nan sub norm inf) %x ) {
1430
+ ; CHECK-LABEL: @test_zero_only(
1431
+ ; CHECK-NEXT: [[TMP1:%.*]] = call float @llvm.fabs.f32(float [[X:%.*]])
1432
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast float [[TMP1]] to i32
1433
+ ; CHECK-NEXT: ret i32 [[AND]]
1434
+ ;
1435
+ %y = bitcast float %x to i32
1436
+ %and = and i32 %y , 2147483647
1437
+ ret i32 %and
1438
+ }
1439
+
1440
+ define i80 @test_zero_only_non_ieee (x86_fp80 nofpclass(nan sub norm inf) %x ) {
1441
+ ; CHECK-LABEL: @test_zero_only_non_ieee(
1442
+ ; CHECK-NEXT: [[TMP1:%.*]] = call x86_fp80 @llvm.fabs.f80(x86_fp80 [[X:%.*]])
1443
+ ; CHECK-NEXT: [[AND:%.*]] = bitcast x86_fp80 [[TMP1]] to i80
1444
+ ; CHECK-NEXT: ret i80 [[AND]]
1445
+ ;
1446
+ %y = bitcast x86_fp80 %x to i80
1447
+ %and = and i80 %y , 604462909807314587353087
1448
+ ret i80 %and
1449
+ }
1450
+
1451
+ define i32 @test_inf_nan_only (float nofpclass(sub norm zero) %x ) {
1452
+ ; CHECK-LABEL: @test_inf_nan_only(
1453
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1454
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1455
+ ; CHECK-NEXT: ret i32 [[AND]]
1456
+ ;
1457
+ %y = bitcast float %x to i32
1458
+ %and = and i32 %y , 2130706432
1459
+ ret i32 %and
1460
+ }
1461
+
1462
+ define i32 @test_sub_zero_only (float nofpclass(nan norm inf) %x ) {
1463
+ ; CHECK-LABEL: @test_sub_zero_only(
1464
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1465
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 2130706432
1466
+ ; CHECK-NEXT: ret i32 [[AND]]
1467
+ ;
1468
+ %y = bitcast float %x to i32
1469
+ %and = and i32 %y , 2130706432
1470
+ ret i32 %and
1471
+ }
1472
+
1473
+ define i32 @test_inf_zero_only (float nofpclass(nan norm sub ) %x ) {
1474
+ ; CHECK-LABEL: @test_inf_zero_only(
1475
+ ; CHECK-NEXT: [[Y:%.*]] = bitcast float [[X:%.*]] to i32
1476
+ ; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y]], 16777215
1477
+ ; CHECK-NEXT: ret i32 [[AND]]
1478
+ ;
1479
+ %y = bitcast float %x to i32
1480
+ %and = and i32 %y , 16777215
1481
+ ret i32 %and
1482
+ }
1483
+
1484
+ define i1 @test_simplify_icmp (i32 %x ) {
1485
+ ; CHECK-LABEL: @test_simplify_icmp(
1486
+ ; CHECK-NEXT: [[CAST1:%.*]] = uitofp i32 [[X:%.*]] to double
1487
+ ; CHECK-NEXT: [[CAST2:%.*]] = bitcast double [[CAST1]] to i64
1488
+ ; CHECK-NEXT: [[MASK:%.*]] = and i64 [[CAST2]], -140737488355328
1489
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[MASK]], -1970324836974592
1490
+ ; CHECK-NEXT: ret i1 [[CMP]]
1491
+ ;
1492
+ %cast1 = uitofp i32 %x to double
1493
+ %cast2 = bitcast double %cast1 to i64
1494
+ %mask = and i64 %cast2 , -140737488355328
1495
+ %cmp = icmp eq i64 %mask , -1970324836974592
1496
+ ret i1 %cmp
1497
+ }
1498
+
1499
+ define i16 @test_simplify_mask (i32 %ui , float %x ) {
1500
+ ; CHECK-LABEL: @test_simplify_mask(
1501
+ ; CHECK-NEXT: [[CONV:%.*]] = uitofp i32 [[UI:%.*]] to float
1502
+ ; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[CONV]], [[X:%.*]]
1503
+ ; CHECK-NEXT: br i1 [[CMP]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
1504
+ ; CHECK: if.end:
1505
+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast float [[CONV]] to i32
1506
+ ; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[CAST]], 16
1507
+ ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[SHR]] to i16
1508
+ ; CHECK-NEXT: [[AND:%.*]] = and i16 [[TRUNC]], -32768
1509
+ ; CHECK-NEXT: [[OR:%.*]] = or disjoint i16 [[AND]], 31744
1510
+ ; CHECK-NEXT: ret i16 [[OR]]
1511
+ ; CHECK: if.else:
1512
+ ; CHECK-NEXT: ret i16 0
1513
+ ;
1514
+ %conv = uitofp i32 %ui to float
1515
+ %cmp = fcmp olt float %x , %conv
1516
+ br i1 %cmp , label %if.else , label %if.end
1517
+
1518
+ if.end:
1519
+ %cast = bitcast float %conv to i32
1520
+ %shr = lshr i32 %cast , 16
1521
+ %trunc = trunc i32 %shr to i16
1522
+ %and = and i16 %trunc , -32768
1523
+ %or = or disjoint i16 %and , 31744
1524
+ ret i16 %or
1525
+
1526
+ if.else:
1527
+ ret i16 0
1528
+ }
1529
+
1530
+ ; TODO: %cmp always evaluates to false
1531
+
1532
+ define i1 @test_simplify_icmp2 (double %x ) {
1533
+ ; CHECK-LABEL: @test_simplify_icmp2(
1534
+ ; CHECK-NEXT: [[ABS:%.*]] = tail call double @llvm.fabs.f64(double [[X:%.*]])
1535
+ ; CHECK-NEXT: [[COND:%.*]] = fcmp oeq double [[ABS]], 0x7FF0000000000000
1536
+ ; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1537
+ ; CHECK: if.then:
1538
+ ; CHECK-NEXT: [[CAST:%.*]] = bitcast double [[X]] to i64
1539
+ ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[CAST]], 3458764513820540928
1540
+ ; CHECK-NEXT: ret i1 [[CMP]]
1541
+ ; CHECK: if.else:
1542
+ ; CHECK-NEXT: ret i1 false
1543
+ ;
1544
+ %abs = tail call double @llvm.fabs.f64 (double %x )
1545
+ %cond = fcmp oeq double %abs , 0x7FF0000000000000
1546
+ br i1 %cond , label %if.then , label %if.else
1547
+
1548
+ if.then:
1549
+ %cast = bitcast double %x to i64
1550
+ %cmp = icmp eq i64 %cast , 3458764513820540928
1551
+ ret i1 %cmp
1552
+
1553
+ if.else:
1554
+ ret i1 false
1555
+ }
1556
+
1377
1557
declare void @use (i1 )
1378
1558
declare void @sink (i8 )
0 commit comments