Skip to content

Commit 4d0c25f

Browse files
authored
[RISCV] Select disjoint_or+not as xnor. (#147636)
A disjoint OR can be converted to XOR. And a XOR+NOT is XNOR. Idea taken from #147279. I changed the existing xnor pattern to have the not on the outside instead of the inside. These are equivalent for xor since xor is associative. Tablegen was already generating multiple variants of the isel pattern using associativity. There are some issues here. The disjoint flag isn't preserved through type legalization. I was hoping we could recover it manually for the masked merge cases, but that doesn't work either.
1 parent 5776915 commit 4d0c25f

File tree

8 files changed

+371
-116
lines changed

8 files changed

+371
-116
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3432,7 +3432,7 @@ bool RISCVDAGToDAGISel::selectSHXADD_UWOp(SDValue N, unsigned ShAmt,
34323432
return false;
34333433
}
34343434

3435-
bool RISCVDAGToDAGISel::orIsAdd(const SDNode *N) const {
3435+
bool RISCVDAGToDAGISel::orDisjoint(const SDNode *N) const {
34363436
if (N->getFlags().hasDisjoint())
34373437
return true;
34383438
KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0);
@@ -3465,7 +3465,7 @@ bool RISCVDAGToDAGISel::selectZExtImm32(SDValue N, SDValue &Val) {
34653465
case ISD::ADD:
34663466
break;
34673467
case ISD::OR:
3468-
if (orIsAdd(U))
3468+
if (orDisjoint(U))
34693469
break;
34703470
return false;
34713471
default:

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
125125
bool selectNegImm(SDValue N, SDValue &Val);
126126
bool selectInvLogicImm(SDValue N, SDValue &Val);
127127

128-
bool orIsAdd(const SDNode *Node) const;
128+
bool orDisjoint(const SDNode *Node) const;
129129
bool hasAllNBitUsers(SDNode *Node, unsigned Bits,
130130
const unsigned Depth = 0) const;
131131
bool hasAllBUsers(SDNode *Node) const { return hasAllNBitUsers(Node, 8); }

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,15 +1450,19 @@ def : PatGprUimmLog2XLen<sra, SRAI>;
14501450

14511451
// Select 'or' as ADDI if the immediate bits are known to be 0 in $rs1. This
14521452
// can improve compressibility.
1453-
def or_is_add : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
1454-
return orIsAdd(N);
1453+
def riscv_or_disjoint : PatFrag<(ops node:$lhs, node:$rhs), (or node:$lhs, node:$rhs),[{
1454+
return orDisjoint(N);
14551455
}]>;
1456-
def : PatGprSimm12<or_is_add, ADDI>;
1456+
def : PatGprSimm12<riscv_or_disjoint, ADDI>;
14571457

14581458
def add_like : PatFrags<(ops node:$lhs, node:$rhs),
1459-
[(or_is_add node:$lhs, node:$rhs),
1459+
[(riscv_or_disjoint node:$lhs, node:$rhs),
14601460
(add node:$lhs, node:$rhs)]>;
14611461

1462+
def riscv_xor_like : PatFrags<(ops node:$lhs, node:$rhs),
1463+
[(riscv_or_disjoint node:$lhs, node:$rhs),
1464+
(xor node:$lhs, node:$rhs)]>;
1465+
14621466
// negate of low bit can be done via two (compressible) shifts. The negate
14631467
// is never compressible since rs1 and rd can't be the same register.
14641468
def : Pat<(i32 (sub 0, (and_oneuse GPR:$rs, 1))),
@@ -2160,7 +2164,7 @@ def : PatGprImm<binop_allwusers<xor>, XORI, u32simm12>;
21602164
// Select 'or' as ADDIW if the immediate bits are known to be 0 in $rs1 and
21612165
// $rs1 is sign extended. This can improve compressibility. Using ADDIW gives
21622166
// more power to RISCVOptWInstrs.
2163-
def : Pat<(or_is_add 33signbits_node:$rs1, simm12:$imm),
2167+
def : Pat<(riscv_or_disjoint 33signbits_node:$rs1, simm12:$imm),
21642168
(ADDIW $rs1, simm12:$imm)>;
21652169

21662170
/// Loads

llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,11 +931,11 @@ multiclass VPatWidenOrDisjoint_VV_VX<SDNode extop, string instruction_name> {
931931
defvar wti = vtiToWti.Wti;
932932
let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates,
933933
GetVTypePredicates<wti>.Predicates) in {
934-
def : Pat<(wti.Vector (extop (vti.Vector (or_is_add vti.RegClass:$rs2, vti.RegClass:$rs1)))),
934+
def : Pat<(wti.Vector (extop (vti.Vector (riscv_or_disjoint vti.RegClass:$rs2, vti.RegClass:$rs1)))),
935935
(!cast<Instruction>(instruction_name#"_VV_"#vti.LMul.MX)
936936
(wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
937937
vti.RegClass:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;
938-
def : Pat<(wti.Vector (extop (vti.Vector (or_is_add vti.RegClass:$rs2, (SplatPat (XLenVT GPR:$rs1)))))),
938+
def : Pat<(wti.Vector (extop (vti.Vector (riscv_or_disjoint vti.RegClass:$rs2, (SplatPat (XLenVT GPR:$rs1)))))),
939939
(!cast<Instruction>(instruction_name#"_VX_"#vti.LMul.MX)
940940
(wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2,
941941
GPR:$rs1, vti.AVL, vti.Log2SEW, TA_MA)>;

llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ let HasOneUse = 1 in {
653653
node:$E),
654654
(riscv_or_vl node:$A, node:$B, node:$C,
655655
node:$D, node:$E), [{
656-
return orIsAdd(N);
656+
return orDisjoint(N);
657657
}]>;
658658
def riscv_sub_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D,
659659
node:$E),

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,8 @@ def invLogicImm : ComplexPattern<XLenVT, 1, "selectInvLogicImm", [], [], 0>;
497497
let Predicates = [HasStdExtZbbOrZbkb] in {
498498
def : Pat<(XLenVT (and GPR:$rs1, (not GPR:$rs2))), (ANDN GPR:$rs1, GPR:$rs2)>;
499499
def : Pat<(XLenVT (or GPR:$rs1, (not GPR:$rs2))), (ORN GPR:$rs1, GPR:$rs2)>;
500-
def : Pat<(XLenVT (xor GPR:$rs1, (not GPR:$rs2))), (XNOR GPR:$rs1, GPR:$rs2)>;
500+
def : Pat<(XLenVT (not (riscv_xor_like GPR:$rs1, GPR:$rs2))),
501+
(XNOR GPR:$rs1, GPR:$rs2)>;
501502

502503
def : Pat<(XLenVT (and GPR:$rs1, invLogicImm:$rs2)), (ANDN GPR:$rs1, invLogicImm:$rs2)>;
503504
def : Pat<(XLenVT (or GPR:$rs1, invLogicImm:$rs2)), (ORN GPR:$rs1, invLogicImm:$rs2)>;

0 commit comments

Comments
 (0)