[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