Skip to content

Commit 02fad05

Browse files
authored
[RISCV][SDAG] Fold select c, ~x, x into xor -c, x (#82462)
This patch lowers select of constants if `TrueV == ~FalseV`. Address the comment in #82456 (comment).
1 parent 1246b64 commit 02fad05

File tree

2 files changed

+187
-0
lines changed

2 files changed

+187
-0
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7239,6 +7239,16 @@ static SDValue combineSelectToBinOp(SDNode *N, SelectionDAG &DAG,
72397239
}
72407240
}
72417241

7242+
// select c, ~x, x --> xor -c, x
7243+
if (isa<ConstantSDNode>(TrueV) && isa<ConstantSDNode>(FalseV)) {
7244+
const APInt &TrueVal = TrueV->getAsAPIntVal();
7245+
const APInt &FalseVal = FalseV->getAsAPIntVal();
7246+
if (~TrueVal == FalseVal) {
7247+
SDValue Neg = DAG.getNegative(CondV, DL, VT);
7248+
return DAG.getNode(ISD::XOR, DL, VT, Neg, FalseV);
7249+
}
7250+
}
7251+
72427252
// Try to fold (select (setcc lhs, rhs, cc), truev, falsev) into bitwise ops
72437253
// when both truev and falsev are also setcc.
72447254
if (CondV.getOpcode() == ISD::SETCC && TrueV.getOpcode() == ISD::SETCC &&

llvm/test/CodeGen/RISCV/select.ll

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,3 +1449,180 @@ entry:
14491449
%res = select i1 %cond, i32 %a, i32 %c
14501450
ret i32 %res
14511451
}
1452+
1453+
define i32 @select_cst_not1(i32 signext %a, i32 signext %b) {
1454+
; CHECK-LABEL: select_cst_not1:
1455+
; CHECK: # %bb.0:
1456+
; CHECK-NEXT: slt a0, a0, a1
1457+
; CHECK-NEXT: neg a0, a0
1458+
; CHECK-NEXT: xori a0, a0, -6
1459+
; CHECK-NEXT: ret
1460+
%cond = icmp slt i32 %a, %b
1461+
%ret = select i1 %cond, i32 5, i32 -6
1462+
ret i32 %ret
1463+
}
1464+
1465+
define i32 @select_cst_not2(i32 signext %a) {
1466+
; CHECK-LABEL: select_cst_not2:
1467+
; CHECK: # %bb.0:
1468+
; CHECK-NEXT: srai a0, a0, 31
1469+
; CHECK-NEXT: xori a0, a0, -6
1470+
; CHECK-NEXT: ret
1471+
%cond = icmp slt i32 %a, 0
1472+
%ret = select i1 %cond, i32 5, i32 -6
1473+
ret i32 %ret
1474+
}
1475+
1476+
define i32 @select_cst_not3(i32 signext %a) {
1477+
; CHECK-LABEL: select_cst_not3:
1478+
; CHECK: # %bb.0:
1479+
; CHECK-NEXT: srai a0, a0, 31
1480+
; CHECK-NEXT: xori a0, a0, 5
1481+
; CHECK-NEXT: ret
1482+
%cond = icmp sgt i32 %a, -1
1483+
%ret = select i1 %cond, i32 5, i32 -6
1484+
ret i32 %ret
1485+
}
1486+
1487+
define i32 @select_cst_not4(i32 signext %a, i32 signext %b) {
1488+
; RV32IM-LABEL: select_cst_not4:
1489+
; RV32IM: # %bb.0:
1490+
; RV32IM-NEXT: slt a0, a0, a1
1491+
; RV32IM-NEXT: lui a1, 524288
1492+
; RV32IM-NEXT: addi a1, a1, -1
1493+
; RV32IM-NEXT: add a0, a0, a1
1494+
; RV32IM-NEXT: ret
1495+
;
1496+
; RV64IM-LABEL: select_cst_not4:
1497+
; RV64IM: # %bb.0:
1498+
; RV64IM-NEXT: slt a0, a0, a1
1499+
; RV64IM-NEXT: neg a0, a0
1500+
; RV64IM-NEXT: lui a1, 524288
1501+
; RV64IM-NEXT: addiw a1, a1, -1
1502+
; RV64IM-NEXT: xor a0, a0, a1
1503+
; RV64IM-NEXT: ret
1504+
;
1505+
; RV64IMXVTCONDOPS-LABEL: select_cst_not4:
1506+
; RV64IMXVTCONDOPS: # %bb.0:
1507+
; RV64IMXVTCONDOPS-NEXT: slt a0, a0, a1
1508+
; RV64IMXVTCONDOPS-NEXT: neg a0, a0
1509+
; RV64IMXVTCONDOPS-NEXT: lui a1, 524288
1510+
; RV64IMXVTCONDOPS-NEXT: addiw a1, a1, -1
1511+
; RV64IMXVTCONDOPS-NEXT: xor a0, a0, a1
1512+
; RV64IMXVTCONDOPS-NEXT: ret
1513+
;
1514+
; RV32IMZICOND-LABEL: select_cst_not4:
1515+
; RV32IMZICOND: # %bb.0:
1516+
; RV32IMZICOND-NEXT: slt a0, a0, a1
1517+
; RV32IMZICOND-NEXT: lui a1, 524288
1518+
; RV32IMZICOND-NEXT: addi a1, a1, -1
1519+
; RV32IMZICOND-NEXT: add a0, a0, a1
1520+
; RV32IMZICOND-NEXT: ret
1521+
;
1522+
; RV64IMZICOND-LABEL: select_cst_not4:
1523+
; RV64IMZICOND: # %bb.0:
1524+
; RV64IMZICOND-NEXT: slt a0, a0, a1
1525+
; RV64IMZICOND-NEXT: neg a0, a0
1526+
; RV64IMZICOND-NEXT: lui a1, 524288
1527+
; RV64IMZICOND-NEXT: addiw a1, a1, -1
1528+
; RV64IMZICOND-NEXT: xor a0, a0, a1
1529+
; RV64IMZICOND-NEXT: ret
1530+
%cond = icmp slt i32 %a, %b
1531+
%ret = select i1 %cond, i32 -2147483648, i32 2147483647
1532+
ret i32 %ret
1533+
}
1534+
1535+
define i32 @select_cst_not5(i32 signext %a, i32 signext %b) {
1536+
; RV32IM-LABEL: select_cst_not5:
1537+
; RV32IM: # %bb.0:
1538+
; RV32IM-NEXT: slt a0, a0, a1
1539+
; RV32IM-NEXT: neg a0, a0
1540+
; RV32IM-NEXT: lui a1, 16
1541+
; RV32IM-NEXT: addi a1, a1, -5
1542+
; RV32IM-NEXT: xor a0, a0, a1
1543+
; RV32IM-NEXT: ret
1544+
;
1545+
; RV64IM-LABEL: select_cst_not5:
1546+
; RV64IM: # %bb.0:
1547+
; RV64IM-NEXT: slt a0, a0, a1
1548+
; RV64IM-NEXT: neg a0, a0
1549+
; RV64IM-NEXT: lui a1, 16
1550+
; RV64IM-NEXT: addiw a1, a1, -5
1551+
; RV64IM-NEXT: xor a0, a0, a1
1552+
; RV64IM-NEXT: ret
1553+
;
1554+
; RV64IMXVTCONDOPS-LABEL: select_cst_not5:
1555+
; RV64IMXVTCONDOPS: # %bb.0:
1556+
; RV64IMXVTCONDOPS-NEXT: slt a0, a0, a1
1557+
; RV64IMXVTCONDOPS-NEXT: neg a0, a0
1558+
; RV64IMXVTCONDOPS-NEXT: lui a1, 16
1559+
; RV64IMXVTCONDOPS-NEXT: addiw a1, a1, -5
1560+
; RV64IMXVTCONDOPS-NEXT: xor a0, a0, a1
1561+
; RV64IMXVTCONDOPS-NEXT: ret
1562+
;
1563+
; RV32IMZICOND-LABEL: select_cst_not5:
1564+
; RV32IMZICOND: # %bb.0:
1565+
; RV32IMZICOND-NEXT: slt a0, a0, a1
1566+
; RV32IMZICOND-NEXT: neg a0, a0
1567+
; RV32IMZICOND-NEXT: lui a1, 16
1568+
; RV32IMZICOND-NEXT: addi a1, a1, -5
1569+
; RV32IMZICOND-NEXT: xor a0, a0, a1
1570+
; RV32IMZICOND-NEXT: ret
1571+
;
1572+
; RV64IMZICOND-LABEL: select_cst_not5:
1573+
; RV64IMZICOND: # %bb.0:
1574+
; RV64IMZICOND-NEXT: slt a0, a0, a1
1575+
; RV64IMZICOND-NEXT: neg a0, a0
1576+
; RV64IMZICOND-NEXT: lui a1, 16
1577+
; RV64IMZICOND-NEXT: addiw a1, a1, -5
1578+
; RV64IMZICOND-NEXT: xor a0, a0, a1
1579+
; RV64IMZICOND-NEXT: ret
1580+
%cond = icmp slt i32 %a, %b
1581+
%ret = select i1 %cond, i32 -65532, i32 65531
1582+
ret i32 %ret
1583+
}
1584+
1585+
define i32 @select_cst_unknown(i32 signext %a, i32 signext %b) {
1586+
; RV32IM-LABEL: select_cst_unknown:
1587+
; RV32IM: # %bb.0:
1588+
; RV32IM-NEXT: mv a2, a0
1589+
; RV32IM-NEXT: li a0, 5
1590+
; RV32IM-NEXT: blt a2, a1, .LBB42_2
1591+
; RV32IM-NEXT: # %bb.1:
1592+
; RV32IM-NEXT: li a0, -7
1593+
; RV32IM-NEXT: .LBB42_2:
1594+
; RV32IM-NEXT: ret
1595+
;
1596+
; RV64IM-LABEL: select_cst_unknown:
1597+
; RV64IM: # %bb.0:
1598+
; RV64IM-NEXT: mv a2, a0
1599+
; RV64IM-NEXT: li a0, 5
1600+
; RV64IM-NEXT: blt a2, a1, .LBB42_2
1601+
; RV64IM-NEXT: # %bb.1:
1602+
; RV64IM-NEXT: li a0, -7
1603+
; RV64IM-NEXT: .LBB42_2:
1604+
; RV64IM-NEXT: ret
1605+
;
1606+
; RV64IMXVTCONDOPS-LABEL: select_cst_unknown:
1607+
; RV64IMXVTCONDOPS: # %bb.0:
1608+
; RV64IMXVTCONDOPS-NEXT: slt a0, a0, a1
1609+
; RV64IMXVTCONDOPS-NEXT: li a1, -7
1610+
; RV64IMXVTCONDOPS-NEXT: vt.maskcn a1, a1, a0
1611+
; RV64IMXVTCONDOPS-NEXT: li a2, 5
1612+
; RV64IMXVTCONDOPS-NEXT: vt.maskc a0, a2, a0
1613+
; RV64IMXVTCONDOPS-NEXT: or a0, a0, a1
1614+
; RV64IMXVTCONDOPS-NEXT: ret
1615+
;
1616+
; CHECKZICOND-LABEL: select_cst_unknown:
1617+
; CHECKZICOND: # %bb.0:
1618+
; CHECKZICOND-NEXT: slt a0, a0, a1
1619+
; CHECKZICOND-NEXT: li a1, -7
1620+
; CHECKZICOND-NEXT: czero.nez a1, a1, a0
1621+
; CHECKZICOND-NEXT: li a2, 5
1622+
; CHECKZICOND-NEXT: czero.eqz a0, a2, a0
1623+
; CHECKZICOND-NEXT: or a0, a0, a1
1624+
; CHECKZICOND-NEXT: ret
1625+
%cond = icmp slt i32 %a, %b
1626+
%ret = select i1 %cond, i32 5, i32 -7
1627+
ret i32 %ret
1628+
}

0 commit comments

Comments
 (0)