Skip to content

Commit b7376c3

Browse files
authored
[RISCV][NFC] Add comments and tests for frint case of performFP_TO_INT_SATCombine. (#76014)
performFP_TO_INT_SATCombine could also serve pattern (fp_to_int_sat (frint X)).
1 parent 9a41a80 commit b7376c3

File tree

4 files changed

+1242
-0
lines changed

4 files changed

+1242
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13594,6 +13594,7 @@ static SDValue performFP_TO_INTCombine(SDNode *N,
1359413594
// (fp_to_int_sat (ffloor X)) -> (select X == nan, 0, (fcvt X, rdn))
1359513595
// (fp_to_int_sat (fceil X)) -> (select X == nan, 0, (fcvt X, rup))
1359613596
// (fp_to_int_sat (fround X)) -> (select X == nan, 0, (fcvt X, rmm))
13597+
// (fp_to_int_sat (frint X)) -> (select X == nan, 0, (fcvt X, dyn))
1359713598
static SDValue performFP_TO_INT_SATCombine(SDNode *N,
1359813599
TargetLowering::DAGCombinerInfo &DCI,
1359913600
const RISCVSubtarget &Subtarget) {

llvm/test/CodeGen/RISCV/double-round-conv-sat.ll

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,11 +1338,278 @@ define i64 @test_roundeven_ui64(double %x) nounwind {
13381338
ret i64 %b
13391339
}
13401340

1341+
define signext i32 @test_rint_si32(double %x) {
1342+
; CHECKIFD-LABEL: test_rint_si32:
1343+
; CHECKIFD: # %bb.0:
1344+
; CHECKIFD-NEXT: fcvt.w.d a0, fa0
1345+
; CHECKIFD-NEXT: feq.d a1, fa0, fa0
1346+
; CHECKIFD-NEXT: seqz a1, a1
1347+
; CHECKIFD-NEXT: addi a1, a1, -1
1348+
; CHECKIFD-NEXT: and a0, a1, a0
1349+
; CHECKIFD-NEXT: ret
1350+
;
1351+
; RV32IZFINXZDINX-LABEL: test_rint_si32:
1352+
; RV32IZFINXZDINX: # %bb.0:
1353+
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1354+
; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16
1355+
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1356+
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1357+
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1358+
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1359+
; RV32IZFINXZDINX-NEXT: fcvt.w.d a2, a0
1360+
; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0
1361+
; RV32IZFINXZDINX-NEXT: seqz a0, a0
1362+
; RV32IZFINXZDINX-NEXT: addi a0, a0, -1
1363+
; RV32IZFINXZDINX-NEXT: and a0, a0, a2
1364+
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1365+
; RV32IZFINXZDINX-NEXT: ret
1366+
;
1367+
; RV64IZFINXZDINX-LABEL: test_rint_si32:
1368+
; RV64IZFINXZDINX: # %bb.0:
1369+
; RV64IZFINXZDINX-NEXT: fcvt.w.d a1, a0
1370+
; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a0
1371+
; RV64IZFINXZDINX-NEXT: seqz a0, a0
1372+
; RV64IZFINXZDINX-NEXT: addi a0, a0, -1
1373+
; RV64IZFINXZDINX-NEXT: and a0, a0, a1
1374+
; RV64IZFINXZDINX-NEXT: ret
1375+
%a = call double @llvm.rint.f64(double %x)
1376+
%b = call i32 @llvm.fptosi.sat.i32.f64(double %a)
1377+
ret i32 %b
1378+
}
1379+
1380+
define i64 @test_rint_si64(double %x) nounwind {
1381+
; RV32IFD-LABEL: test_rint_si64:
1382+
; RV32IFD: # %bb.0:
1383+
; RV32IFD-NEXT: addi sp, sp, -16
1384+
; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1385+
; RV32IFD-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
1386+
; RV32IFD-NEXT: fsd fs0, 0(sp) # 8-byte Folded Spill
1387+
; RV32IFD-NEXT: call rint@plt
1388+
; RV32IFD-NEXT: lui a0, %hi(.LCPI21_0)
1389+
; RV32IFD-NEXT: fld fa5, %lo(.LCPI21_0)(a0)
1390+
; RV32IFD-NEXT: fmv.d fs0, fa0
1391+
; RV32IFD-NEXT: fle.d s0, fa5, fa0
1392+
; RV32IFD-NEXT: call __fixdfdi@plt
1393+
; RV32IFD-NEXT: lui a4, 524288
1394+
; RV32IFD-NEXT: lui a2, 524288
1395+
; RV32IFD-NEXT: beqz s0, .LBB21_2
1396+
; RV32IFD-NEXT: # %bb.1:
1397+
; RV32IFD-NEXT: mv a2, a1
1398+
; RV32IFD-NEXT: .LBB21_2:
1399+
; RV32IFD-NEXT: lui a1, %hi(.LCPI21_1)
1400+
; RV32IFD-NEXT: fld fa5, %lo(.LCPI21_1)(a1)
1401+
; RV32IFD-NEXT: flt.d a3, fa5, fs0
1402+
; RV32IFD-NEXT: beqz a3, .LBB21_4
1403+
; RV32IFD-NEXT: # %bb.3:
1404+
; RV32IFD-NEXT: addi a2, a4, -1
1405+
; RV32IFD-NEXT: .LBB21_4:
1406+
; RV32IFD-NEXT: feq.d a1, fs0, fs0
1407+
; RV32IFD-NEXT: neg a4, a1
1408+
; RV32IFD-NEXT: and a1, a4, a2
1409+
; RV32IFD-NEXT: neg a2, a3
1410+
; RV32IFD-NEXT: neg a3, s0
1411+
; RV32IFD-NEXT: and a0, a3, a0
1412+
; RV32IFD-NEXT: or a0, a2, a0
1413+
; RV32IFD-NEXT: and a0, a4, a0
1414+
; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1415+
; RV32IFD-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
1416+
; RV32IFD-NEXT: fld fs0, 0(sp) # 8-byte Folded Reload
1417+
; RV32IFD-NEXT: addi sp, sp, 16
1418+
; RV32IFD-NEXT: ret
1419+
;
1420+
; RV64IFD-LABEL: test_rint_si64:
1421+
; RV64IFD: # %bb.0:
1422+
; RV64IFD-NEXT: fcvt.l.d a0, fa0
1423+
; RV64IFD-NEXT: feq.d a1, fa0, fa0
1424+
; RV64IFD-NEXT: seqz a1, a1
1425+
; RV64IFD-NEXT: addi a1, a1, -1
1426+
; RV64IFD-NEXT: and a0, a1, a0
1427+
; RV64IFD-NEXT: ret
1428+
;
1429+
; RV32IZFINXZDINX-LABEL: test_rint_si64:
1430+
; RV32IZFINXZDINX: # %bb.0:
1431+
; RV32IZFINXZDINX-NEXT: addi sp, sp, -32
1432+
; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1433+
; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1434+
; RV32IZFINXZDINX-NEXT: sw s2, 20(sp) # 4-byte Folded Spill
1435+
; RV32IZFINXZDINX-NEXT: sw s3, 16(sp) # 4-byte Folded Spill
1436+
; RV32IZFINXZDINX-NEXT: call rint@plt
1437+
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1438+
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1439+
; RV32IZFINXZDINX-NEXT: lw s2, 8(sp)
1440+
; RV32IZFINXZDINX-NEXT: lw s3, 12(sp)
1441+
; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI21_0)
1442+
; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI21_0+4)(a2)
1443+
; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI21_0)(a2)
1444+
; RV32IZFINXZDINX-NEXT: fle.d s0, a2, s2
1445+
; RV32IZFINXZDINX-NEXT: call __fixdfdi@plt
1446+
; RV32IZFINXZDINX-NEXT: lui a4, 524288
1447+
; RV32IZFINXZDINX-NEXT: lui a2, 524288
1448+
; RV32IZFINXZDINX-NEXT: beqz s0, .LBB21_2
1449+
; RV32IZFINXZDINX-NEXT: # %bb.1:
1450+
; RV32IZFINXZDINX-NEXT: mv a2, a1
1451+
; RV32IZFINXZDINX-NEXT: .LBB21_2:
1452+
; RV32IZFINXZDINX-NEXT: lui a1, %hi(.LCPI21_1)
1453+
; RV32IZFINXZDINX-NEXT: lw a6, %lo(.LCPI21_1)(a1)
1454+
; RV32IZFINXZDINX-NEXT: lw a7, %lo(.LCPI21_1+4)(a1)
1455+
; RV32IZFINXZDINX-NEXT: flt.d a3, a6, s2
1456+
; RV32IZFINXZDINX-NEXT: beqz a3, .LBB21_4
1457+
; RV32IZFINXZDINX-NEXT: # %bb.3:
1458+
; RV32IZFINXZDINX-NEXT: addi a2, a4, -1
1459+
; RV32IZFINXZDINX-NEXT: .LBB21_4:
1460+
; RV32IZFINXZDINX-NEXT: feq.d a1, s2, s2
1461+
; RV32IZFINXZDINX-NEXT: neg a4, a1
1462+
; RV32IZFINXZDINX-NEXT: and a1, a4, a2
1463+
; RV32IZFINXZDINX-NEXT: neg a2, s0
1464+
; RV32IZFINXZDINX-NEXT: and a0, a2, a0
1465+
; RV32IZFINXZDINX-NEXT: neg a2, a3
1466+
; RV32IZFINXZDINX-NEXT: or a0, a2, a0
1467+
; RV32IZFINXZDINX-NEXT: and a0, a4, a0
1468+
; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1469+
; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1470+
; RV32IZFINXZDINX-NEXT: lw s2, 20(sp) # 4-byte Folded Reload
1471+
; RV32IZFINXZDINX-NEXT: lw s3, 16(sp) # 4-byte Folded Reload
1472+
; RV32IZFINXZDINX-NEXT: addi sp, sp, 32
1473+
; RV32IZFINXZDINX-NEXT: ret
1474+
;
1475+
; RV64IZFINXZDINX-LABEL: test_rint_si64:
1476+
; RV64IZFINXZDINX: # %bb.0:
1477+
; RV64IZFINXZDINX-NEXT: fcvt.l.d a1, a0
1478+
; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a0
1479+
; RV64IZFINXZDINX-NEXT: seqz a0, a0
1480+
; RV64IZFINXZDINX-NEXT: addi a0, a0, -1
1481+
; RV64IZFINXZDINX-NEXT: and a0, a0, a1
1482+
; RV64IZFINXZDINX-NEXT: ret
1483+
%a = call double @llvm.rint.f64(double %x)
1484+
%b = call i64 @llvm.fptosi.sat.i64.f64(double %a)
1485+
ret i64 %b
1486+
}
1487+
1488+
define signext i32 @test_rint_ui32(double %x) {
1489+
; CHECKIFD-LABEL: test_rint_ui32:
1490+
; CHECKIFD: # %bb.0:
1491+
; CHECKIFD-NEXT: fcvt.wu.d a0, fa0
1492+
; CHECKIFD-NEXT: feq.d a1, fa0, fa0
1493+
; CHECKIFD-NEXT: seqz a1, a1
1494+
; CHECKIFD-NEXT: addi a1, a1, -1
1495+
; CHECKIFD-NEXT: and a0, a1, a0
1496+
; CHECKIFD-NEXT: ret
1497+
;
1498+
; RV32IZFINXZDINX-LABEL: test_rint_ui32:
1499+
; RV32IZFINXZDINX: # %bb.0:
1500+
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
1501+
; RV32IZFINXZDINX-NEXT: .cfi_def_cfa_offset 16
1502+
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1503+
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1504+
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
1505+
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
1506+
; RV32IZFINXZDINX-NEXT: fcvt.wu.d a2, a0
1507+
; RV32IZFINXZDINX-NEXT: feq.d a0, a0, a0
1508+
; RV32IZFINXZDINX-NEXT: seqz a0, a0
1509+
; RV32IZFINXZDINX-NEXT: addi a0, a0, -1
1510+
; RV32IZFINXZDINX-NEXT: and a0, a0, a2
1511+
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
1512+
; RV32IZFINXZDINX-NEXT: ret
1513+
;
1514+
; RV64IZFINXZDINX-LABEL: test_rint_ui32:
1515+
; RV64IZFINXZDINX: # %bb.0:
1516+
; RV64IZFINXZDINX-NEXT: fcvt.wu.d a1, a0
1517+
; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a0
1518+
; RV64IZFINXZDINX-NEXT: seqz a0, a0
1519+
; RV64IZFINXZDINX-NEXT: addi a0, a0, -1
1520+
; RV64IZFINXZDINX-NEXT: and a0, a0, a1
1521+
; RV64IZFINXZDINX-NEXT: ret
1522+
%a = call double @llvm.rint.f64(double %x)
1523+
%b = call i32 @llvm.fptoui.sat.i32.f64(double %a)
1524+
ret i32 %b
1525+
}
1526+
1527+
define i64 @test_rint_ui64(double %x) nounwind {
1528+
; RV32IFD-LABEL: test_rint_ui64:
1529+
; RV32IFD: # %bb.0:
1530+
; RV32IFD-NEXT: addi sp, sp, -16
1531+
; RV32IFD-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
1532+
; RV32IFD-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
1533+
; RV32IFD-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
1534+
; RV32IFD-NEXT: call rint@plt
1535+
; RV32IFD-NEXT: lui a0, %hi(.LCPI23_0)
1536+
; RV32IFD-NEXT: fld fa5, %lo(.LCPI23_0)(a0)
1537+
; RV32IFD-NEXT: flt.d a0, fa5, fa0
1538+
; RV32IFD-NEXT: neg s0, a0
1539+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
1540+
; RV32IFD-NEXT: fle.d a0, fa5, fa0
1541+
; RV32IFD-NEXT: neg s1, a0
1542+
; RV32IFD-NEXT: call __fixunsdfdi@plt
1543+
; RV32IFD-NEXT: and a0, s1, a0
1544+
; RV32IFD-NEXT: or a0, s0, a0
1545+
; RV32IFD-NEXT: and a1, s1, a1
1546+
; RV32IFD-NEXT: or a1, s0, a1
1547+
; RV32IFD-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
1548+
; RV32IFD-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
1549+
; RV32IFD-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
1550+
; RV32IFD-NEXT: addi sp, sp, 16
1551+
; RV32IFD-NEXT: ret
1552+
;
1553+
; RV64IFD-LABEL: test_rint_ui64:
1554+
; RV64IFD: # %bb.0:
1555+
; RV64IFD-NEXT: fcvt.lu.d a0, fa0
1556+
; RV64IFD-NEXT: feq.d a1, fa0, fa0
1557+
; RV64IFD-NEXT: seqz a1, a1
1558+
; RV64IFD-NEXT: addi a1, a1, -1
1559+
; RV64IFD-NEXT: and a0, a1, a0
1560+
; RV64IFD-NEXT: ret
1561+
;
1562+
; RV32IZFINXZDINX-LABEL: test_rint_ui64:
1563+
; RV32IZFINXZDINX: # %bb.0:
1564+
; RV32IZFINXZDINX-NEXT: addi sp, sp, -32
1565+
; RV32IZFINXZDINX-NEXT: sw ra, 28(sp) # 4-byte Folded Spill
1566+
; RV32IZFINXZDINX-NEXT: sw s0, 24(sp) # 4-byte Folded Spill
1567+
; RV32IZFINXZDINX-NEXT: sw s1, 20(sp) # 4-byte Folded Spill
1568+
; RV32IZFINXZDINX-NEXT: sw s2, 16(sp) # 4-byte Folded Spill
1569+
; RV32IZFINXZDINX-NEXT: call rint@plt
1570+
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
1571+
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
1572+
; RV32IZFINXZDINX-NEXT: lw s0, 8(sp)
1573+
; RV32IZFINXZDINX-NEXT: lw s1, 12(sp)
1574+
; RV32IZFINXZDINX-NEXT: fcvt.d.w a2, zero
1575+
; RV32IZFINXZDINX-NEXT: fle.d a2, a2, s0
1576+
; RV32IZFINXZDINX-NEXT: neg s2, a2
1577+
; RV32IZFINXZDINX-NEXT: call __fixunsdfdi@plt
1578+
; RV32IZFINXZDINX-NEXT: lui a2, %hi(.LCPI23_0)
1579+
; RV32IZFINXZDINX-NEXT: lw a3, %lo(.LCPI23_0+4)(a2)
1580+
; RV32IZFINXZDINX-NEXT: lw a2, %lo(.LCPI23_0)(a2)
1581+
; RV32IZFINXZDINX-NEXT: and a0, s2, a0
1582+
; RV32IZFINXZDINX-NEXT: flt.d a2, a2, s0
1583+
; RV32IZFINXZDINX-NEXT: neg a2, a2
1584+
; RV32IZFINXZDINX-NEXT: or a0, a2, a0
1585+
; RV32IZFINXZDINX-NEXT: and a1, s2, a1
1586+
; RV32IZFINXZDINX-NEXT: or a1, a2, a1
1587+
; RV32IZFINXZDINX-NEXT: lw ra, 28(sp) # 4-byte Folded Reload
1588+
; RV32IZFINXZDINX-NEXT: lw s0, 24(sp) # 4-byte Folded Reload
1589+
; RV32IZFINXZDINX-NEXT: lw s1, 20(sp) # 4-byte Folded Reload
1590+
; RV32IZFINXZDINX-NEXT: lw s2, 16(sp) # 4-byte Folded Reload
1591+
; RV32IZFINXZDINX-NEXT: addi sp, sp, 32
1592+
; RV32IZFINXZDINX-NEXT: ret
1593+
;
1594+
; RV64IZFINXZDINX-LABEL: test_rint_ui64:
1595+
; RV64IZFINXZDINX: # %bb.0:
1596+
; RV64IZFINXZDINX-NEXT: fcvt.lu.d a1, a0
1597+
; RV64IZFINXZDINX-NEXT: feq.d a0, a0, a0
1598+
; RV64IZFINXZDINX-NEXT: seqz a0, a0
1599+
; RV64IZFINXZDINX-NEXT: addi a0, a0, -1
1600+
; RV64IZFINXZDINX-NEXT: and a0, a0, a1
1601+
; RV64IZFINXZDINX-NEXT: ret
1602+
%a = call double @llvm.rint.f64(double %x)
1603+
%b = call i64 @llvm.fptoui.sat.i64.f64(double %a)
1604+
ret i64 %b
1605+
}
1606+
13411607
declare double @llvm.floor.f64(double)
13421608
declare double @llvm.ceil.f64(double)
13431609
declare double @llvm.trunc.f64(double)
13441610
declare double @llvm.round.f64(double)
13451611
declare double @llvm.roundeven.f64(double)
1612+
declare double @llvm.rint.f64(double)
13461613
declare i32 @llvm.fptosi.sat.i32.f64(double)
13471614
declare i64 @llvm.fptosi.sat.i64.f64(double)
13481615
declare i32 @llvm.fptoui.sat.i32.f64(double)

0 commit comments

Comments
 (0)