[llvm] 3caa427 - [RISCV] Use ComplexPattern to reduce the number of patterns for XVentanaCondOps.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Feb 24 09:37:46 PST 2023
Author: Craig Topper
Date: 2023-02-24T09:36:58-08:00
New Revision: 3caa427f8ecbf9f5845c15b53e1021db94b3db03
URL: https://github.com/llvm/llvm-project/commit/3caa427f8ecbf9f5845c15b53e1021db94b3db03
DIFF: https://github.com/llvm/llvm-project/commit/3caa427f8ecbf9f5845c15b53e1021db94b3db03.diff
LOG: [RISCV] Use ComplexPattern to reduce the number of patterns for XVentanaCondOps.
XVentanaCondOps check the condition operand for zero or non-zero.
We use this to optimize seteq/setne that would otherwise becomes
xor/xori/addi+snez/seqz. These patterns avoid the snez/seqz.
This patch adds two ComplexPatterns to match the varous cases and
emit the xor/xori/addi instruction.
These patterns can also be used by D144681.
Reviewed By: philipp.tomsich
Differential Revision: https://reviews.llvm.org/D144700
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
llvm/lib/Target/RISCV/RISCVInstrInfo.td
llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index 604ad1f7885d..851652029e22 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -2423,6 +2423,72 @@ bool RISCVDAGToDAGISel::selectShiftMask(SDValue N, unsigned ShiftWidth,
return true;
}
+/// Some instructions have a condition operand that is compared against zero.
+/// Since RISC-V doesn't have seteq/setne instructions, we can use this
+/// property to avoid a seqz or snez instruction after an xor/addi/xori.
+/// When \p Inverse is false, we match seteq or any unknown operation. When
+/// \p Inverse is true, we only match setne.
+bool RISCVDAGToDAGISel::selectCondOp(SDValue N, bool Inverse, SDValue &Val) {
+ // Start with this node as the output.
+ Val = N;
+
+ // If the node isn't a setcc, there's nothing we can do. Return success
+ // if we aren't looking for an inverse condition.
+ if (N->getOpcode() != ISD::SETCC)
+ return !Inverse;
+
+ // If it isn't an equality comparison, we also can't do anything.
+ ISD::CondCode CCVal = cast<CondCodeSDNode>(N->getOperand(2))->get();
+ if (!isIntEqualitySetCC(CCVal))
+ return !Inverse;
+
+ // This ComplexPattern occurs in pairs with both polarities of Inverse.
+ // If this isn't the one we're looking for, let the other polarity match it.
+ if (isTrueWhenEqual(CCVal) != Inverse)
+ return false;
+
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+
+ // If the RHS side is 0, we don't need any extra instructions, return the LHS.
+ if (isNullConstant(RHS)) {
+ Val = LHS;
+ return true;
+ }
+
+ SDLoc DL(N);
+
+ if (auto *C = dyn_cast<ConstantSDNode>(RHS)) {
+ int64_t CVal = C->getSExtValue();
+ // If the RHS is -2048, we can use xori to produce 0 if the LHS is -2048 and
+ // non-zero otherwise.
+ if (CVal == -2048) {
+ Val =
+ SDValue(CurDAG->getMachineNode(
+ RISCV::XORI, DL, N->getValueType(0), LHS,
+ CurDAG->getTargetConstant(CVal, DL, N->getValueType(0))),
+ 0);
+ return true;
+ }
+ // If the RHS is [-2047,2048], we can use addi with -RHS to produce 0 if the
+ // LHS is equal to the RHS and non-zero otherwise.
+ if (isInt<12>(CVal) || CVal == 2048) {
+ Val =
+ SDValue(CurDAG->getMachineNode(
+ RISCV::ADDI, DL, N->getValueType(0), LHS,
+ CurDAG->getTargetConstant(-CVal, DL, N->getValueType(0))),
+ 0);
+ return true;
+ }
+ }
+
+ // If nothing else we can XOR the LHS and RHS to produce zero if they are
+ // equal and a non-zero value if they aren't.
+ Val = SDValue(
+ CurDAG->getMachineNode(RISCV::XOR, DL, N->getValueType(0), LHS, RHS), 0);
+ return true;
+}
+
bool RISCVDAGToDAGISel::selectSExtBits(SDValue N, unsigned Bits, SDValue &Val) {
if (N.getOpcode() == ISD::SIGN_EXTEND_INREG &&
cast<VTSDNode>(N.getOperand(1))->getVT().getSizeInBits() == Bits) {
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
index 3e023f422810..df4671df3840 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h
@@ -86,6 +86,14 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
return selectShiftMask(N, 32, ShAmt);
}
+ bool selectCondOp(SDValue N, bool Inverse, SDValue &Val);
+ bool selectCondOp(SDValue N, SDValue &Val) {
+ return selectCondOp(N, /*Inverse*/ false, Val);
+ }
+ bool selectInverseCondOp(SDValue N, SDValue &Val) {
+ return selectCondOp(N, /*Inverse*/ true, Val);
+ }
+
bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);
template <unsigned Bits> bool selectSExtBits(SDValue N, SDValue &Val) {
return selectSExtBits(N, Bits, Val);
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 52d8a0e30b4a..e6a292db1f61 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1870,6 +1870,15 @@ def : Pat<(binop_allwusers<add> GPR:$rs1, (AddiPair:$rs2)),
(AddiPairImmSmall AddiPair:$rs2))>;
}
+// Some instructions have a condition operand that is compared against zero.
+// Since RISC-V doesn't have seteq/setne instructions, we can use this
+// property to avoid a seqz or snez instruction after an xor/addi/xori.
+// condop matches a setne or any unknown operation.
+// invcondop only matches a seteq.
+// This ComplexPatterns must be used in pairs.
+def condop : ComplexPattern<XLenVT, 1, "selectCondOp">;
+def invcondop : ComplexPattern<XLenVT, 1, "selectInverseCondOp">;
+
/// Empty pseudo for RISCVInitUndefPass
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 0, isCodeGenOnly = 1 in {
def PseudoRVVInitUndefM1 : Pseudo<(outs VR:$vd), (ins), [], "">;
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
index 68c3a2105373..73a06e08de47 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXVentana.td
@@ -30,46 +30,14 @@ def VT_MASKCN : VTMaskedMove<0b111, "vt.maskcn">,
let Predicates = [IsRV64, HasVendorXVentanaCondOps] in {
// Directly use MASKC/MASKCN in case of any of the operands being 0.
-def : Pat<(select GPR:$rc, GPR:$rs1, (i64 0)),
- (VT_MASKC $rs1, $rc)>;
-def : Pat<(select GPR:$rc, (i64 0), GPR:$rs1),
- (VT_MASKCN $rs1, $rc)>;
-
-def : Pat<(select (i64 (setne GPR:$rc, (i64 0))), GPR:$rs1, (i64 0)),
- (VT_MASKC GPR:$rs1, GPR:$rc)>;
-def : Pat<(select (i64 (seteq GPR:$rc, (i64 0))), GPR:$rs1, (i64 0)),
- (VT_MASKCN GPR:$rs1, GPR:$rc)>;
-def : Pat<(select (i64 (setne GPR:$rc, (i64 0))), (i64 0), GPR:$rs1),
- (VT_MASKCN GPR:$rs1, GPR:$rc)>;
-def : Pat<(select (i64 (seteq GPR:$rc, (i64 0))), (i64 0), GPR:$rs1),
- (VT_MASKC GPR:$rs1, GPR:$rc)>;
-
-def : Pat<(select (i64 (setne GPR:$x, simm12_plus1:$y)), GPR:$rs1, (i64 0)),
- (VT_MASKC GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)))>;
-def : Pat<(select (i64 (seteq GPR:$x, simm12_plus1:$y)), GPR:$rs1, (i64 0)),
- (VT_MASKCN GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)))>;
-def : Pat<(select (i64 (setne GPR:$x, simm12_plus1:$y)), (i64 0), GPR:$rs1),
- (VT_MASKCN GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)))>;
-def : Pat<(select (i64 (seteq GPR:$x, simm12_plus1:$y)), (i64 0), GPR:$rs1),
- (VT_MASKC GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)))>;
-
-def : Pat<(select (i64 (setne GPR:$x, (i64 -2048))), GPR:$rs1, (i64 0)),
- (VT_MASKC GPR:$rs1, (XORI GPR:$x, -2048))>;
-def : Pat<(select (i64 (seteq GPR:$x, (i64 -2048))), GPR:$rs1, (i64 0)),
- (VT_MASKCN GPR:$rs1, (XORI GPR:$x, -2048))>;
-def : Pat<(select (i64 (setne GPR:$x, (i64 -2048))), (i64 0), GPR:$rs1),
- (VT_MASKCN GPR:$rs1, (XORI GPR:$x, -2048))>;
-def : Pat<(select (i64 (seteq GPR:$x, (i64 -2048))), (i64 0), GPR:$rs1),
- (VT_MASKC GPR:$rs1, (XORI GPR:$x, -2048))>;
-
-def : Pat<(select (i64 (setne GPR:$x, GPR:$y)), GPR:$rs1, (i64 0)),
- (VT_MASKC GPR:$rs1, (XOR GPR:$x, GPR:$y))>;
-def : Pat<(select (i64 (seteq GPR:$x, GPR:$y)), GPR:$rs1, (i64 0)),
- (VT_MASKCN GPR:$rs1, (XOR GPR:$x, GPR:$y))>;
-def : Pat<(select (i64 (setne GPR:$x, GPR:$y)), (i64 0), GPR:$rs1),
- (VT_MASKCN GPR:$rs1, (XOR GPR:$x, GPR:$y))>;
-def : Pat<(select (i64 (seteq GPR:$x, GPR:$y)), (i64 0), GPR:$rs1),
- (VT_MASKC GPR:$rs1, (XOR GPR:$x, GPR:$y))>;
+def : Pat<(select condop:$rc, GPR:$rs1, (i64 0)),
+ (VT_MASKC GPR:$rs1, condop:$rc)>;
+def : Pat<(select invcondop:$rc, GPR:$rs1, (i64 0)),
+ (VT_MASKCN GPR:$rs1, invcondop:$rc)>;
+def : Pat<(select condop:$rc, (i64 0), GPR:$rs1),
+ (VT_MASKCN GPR:$rs1, condop:$rc)>;
+def : Pat<(select invcondop:$rc, (i64 0), GPR:$rs1),
+ (VT_MASKC GPR:$rs1, invcondop:$rc)>;
// Conditional AND operation patterns.
def : Pat<(i64 (select GPR:$rc, (and GPR:$rs1, GPR:$rs2), GPR:$rs1)),
More information about the llvm-commits
mailing list