mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-28 16:11:29 +00:00
[RISCV] Reuse the condop/invcondop ComplexPatterns for seteq/setne isel. NFC NFC NFC NFC
To do this we need to remove the always matching behavior from condop. This requires us to add more 'select' isel patterns with a bare GPR as the condition. Rename condop/invcondop to riscv_setne/riscv_seteq. This centralizes the ADDI/XORI/XOR tricks into one place.
This commit is contained in:
parent
ab76f5865f
commit
465a48fecb
@ -2423,28 +2423,23 @@ 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;
|
||||
/// RISC-V doesn't have general instructions for integer setne/seteq, but we can
|
||||
/// check for equality with 0. This function emits instructions that convert the
|
||||
/// seteq/setne into something that can be compared with 0.
|
||||
/// When \p Equal is false, we match setne. When \p Equal is true, we match
|
||||
/// seteq.
|
||||
bool RISCVDAGToDAGISel::selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal,
|
||||
SDValue &Val) {
|
||||
assert(ISD::isIntEqualitySetCC(ExpectedCCVal) &&
|
||||
"Unexpected condition code!");
|
||||
|
||||
// If the node isn't a setcc, there's nothing we can do. Return success
|
||||
// if we aren't looking for an inverse condition.
|
||||
// We're looking for a setcc.
|
||||
if (N->getOpcode() != ISD::SETCC)
|
||||
return !Inverse;
|
||||
return false;
|
||||
|
||||
// If it isn't an equality comparison, we also can't do anything.
|
||||
// Must be an equality comparison.
|
||||
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)
|
||||
if (CCVal != ExpectedCCVal)
|
||||
return false;
|
||||
|
||||
SDValue LHS = N->getOperand(0);
|
||||
|
@ -86,12 +86,12 @@ public:
|
||||
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 selectSETCC(SDValue N, ISD::CondCode ExpectedCCVal, SDValue &Val);
|
||||
bool selectSETNE(SDValue N, SDValue &Val) {
|
||||
return selectSETCC(N, ISD::SETNE, Val);
|
||||
}
|
||||
bool selectInverseCondOp(SDValue N, SDValue &Val) {
|
||||
return selectCondOp(N, /*Inverse*/ true, Val);
|
||||
bool selectSETEQ(SDValue N, SDValue &Val) {
|
||||
return selectSETCC(N, ISD::SETEQ, Val);
|
||||
}
|
||||
|
||||
bool selectSExtBits(SDValue N, unsigned Bits, SDValue &Val);
|
||||
|
@ -1332,20 +1332,17 @@ def : PatGprSimm12<setlt, SLTI>;
|
||||
def : PatGprGpr<setult, SLTU>;
|
||||
def : PatGprSimm12<setult, SLTIU>;
|
||||
|
||||
// RISC-V doesn't have general instructions for integer setne/seteq, but we can
|
||||
// check for equality with 0. These ComplexPatterns rewrite the setne/seteq into
|
||||
// something that can be compared with 0.
|
||||
// These ComplexPatterns must be used in pairs.
|
||||
def riscv_setne : ComplexPattern<XLenVT, 1, "selectSETNE", [setcc]>;
|
||||
def riscv_seteq : ComplexPattern<XLenVT, 1, "selectSETEQ", [setcc]>;
|
||||
|
||||
// Define pattern expansions for setcc operations that aren't directly
|
||||
// handled by a RISC-V instruction.
|
||||
def : Pat<(seteq GPR:$rs1, 0), (SLTIU GPR:$rs1, 1)>;
|
||||
def : Pat<(seteq GPR:$rs1, GPR:$rs2), (SLTIU (XOR GPR:$rs1, GPR:$rs2), 1)>;
|
||||
def : Pat<(seteq GPR:$rs1, simm12_plus1:$imm12),
|
||||
(SLTIU (ADDI GPR:$rs1, (NegImm simm12_plus1:$imm12)), 1)>;
|
||||
def : Pat<(seteq GPR:$rs1, -2048),
|
||||
(SLTIU (XORI GPR:$rs1, -2048), 1)>;
|
||||
def : Pat<(setne GPR:$rs1, 0), (SLTU X0, GPR:$rs1)>;
|
||||
def : Pat<(setne GPR:$rs1, GPR:$rs2), (SLTU X0, (XOR GPR:$rs1, GPR:$rs2))>;
|
||||
def : Pat<(setne GPR:$rs1, simm12_plus1:$imm12),
|
||||
(SLTU X0, (ADDI GPR:$rs1, (NegImm simm12_plus1:$imm12)))>;
|
||||
def : Pat<(setne GPR:$rs1, -2048),
|
||||
(SLTU X0, (XORI GPR:$rs1, -2048))>;
|
||||
def : Pat<(riscv_seteq GPR:$rs1), (SLTIU GPR:$rs1, 1)>;
|
||||
def : Pat<(riscv_setne GPR:$rs1), (SLTU X0, GPR:$rs1)>;
|
||||
def : Pat<(setne GPR:$rs1, -1), (SLTIU GPR:$rs1, -1)>;
|
||||
|
||||
def IntCCtoRISCVCC : SDNodeXForm<riscv_selectcc, [{
|
||||
@ -1870,15 +1867,6 @@ 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), [], "">;
|
||||
|
@ -639,18 +639,25 @@ def : Pat<(seteq (and GPR:$rs1, SingleBitSetMask:$mask), 0),
|
||||
} // Predicates = [HasVendorXTHeadBs]
|
||||
|
||||
let Predicates = [HasVendorXTHeadCondMov] in {
|
||||
def : Pat<(select invcondop:$cond, GPR:$a, GPR:$b),
|
||||
(TH_MVNEZ $a, $b, $cond)>;
|
||||
def : Pat<(select condop:$cond, GPR:$a, GPR:$b),
|
||||
(TH_MVEQZ $a, $b, $cond)>;
|
||||
def : Pat<(select invcondop:$cond, GPR:$a, (XLenVT 0)),
|
||||
(TH_MVNEZ $a, X0, $cond)>;
|
||||
def : Pat<(select condop:$cond, GPR:$a, (XLenVT 0)),
|
||||
(TH_MVEQZ $a, X0, $cond)>;
|
||||
def : Pat<(select invcondop:$cond, (XLenVT 0), GPR:$b),
|
||||
(TH_MVEQZ $b, X0, $cond)>;
|
||||
def : Pat<(select condop:$cond, (XLenVT 0), GPR:$b),
|
||||
(TH_MVNEZ $b, X0, $cond)>;
|
||||
def : Pat<(select GPR:$cond, GPR:$a, GPR:$b),
|
||||
(TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
|
||||
def : Pat<(select GPR:$cond, GPR:$a, (XLenVT 0)),
|
||||
(TH_MVEQZ GPR:$a, X0, GPR:$cond)>;
|
||||
def : Pat<(select GPR:$cond, (XLenVT 0), GPR:$b),
|
||||
(TH_MVNEZ GPR:$b, X0, GPR:$cond)>;
|
||||
|
||||
def : Pat<(select (riscv_seteq GPR:$cond), GPR:$a, GPR:$b),
|
||||
(TH_MVNEZ GPR:$a, GPR:$b, GPR:$cond)>;
|
||||
def : Pat<(select (riscv_setne GPR:$cond), GPR:$a, GPR:$b),
|
||||
(TH_MVEQZ GPR:$a, GPR:$b, GPR:$cond)>;
|
||||
def : Pat<(select (riscv_seteq GPR:$cond), GPR:$a, (XLenVT 0)),
|
||||
(TH_MVNEZ GPR:$a, X0, GPR:$cond)>;
|
||||
def : Pat<(select (riscv_setne GPR:$cond), GPR:$a, (XLenVT 0)),
|
||||
(TH_MVEQZ GPR:$a, X0, GPR:$cond)>;
|
||||
def : Pat<(select (riscv_seteq GPR:$cond), (XLenVT 0), GPR:$b),
|
||||
(TH_MVEQZ GPR:$b, X0, GPR:$cond)>;
|
||||
def : Pat<(select (riscv_setne GPR:$cond), (XLenVT 0), GPR:$b),
|
||||
(TH_MVNEZ GPR:$b, X0, GPR:$cond)>;
|
||||
} // Predicates = [HasVendorXTHeadCondMov]
|
||||
|
||||
let Predicates = [HasVendorXTHeadMac] in {
|
||||
|
@ -30,14 +30,19 @@ 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 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)>;
|
||||
def : Pat<(select GPR:$rc, GPR:$rs1, (i64 0)),
|
||||
(VT_MASKC GPR:$rs1, GPR:$rc)>;
|
||||
def : Pat<(select GPR:$rc, (i64 0), GPR:$rs1),
|
||||
(VT_MASKCN GPR:$rs1, GPR:$rc)>;
|
||||
|
||||
def : Pat<(select (riscv_setne GPR:$rc), GPR:$rs1, (i64 0)),
|
||||
(VT_MASKC GPR:$rs1, GPR:$rc)>;
|
||||
def : Pat<(select (riscv_seteq GPR:$rc), GPR:$rs1, (i64 0)),
|
||||
(VT_MASKCN GPR:$rs1, GPR:$rc)>;
|
||||
def : Pat<(select (riscv_setne GPR:$rc), (i64 0), GPR:$rs1),
|
||||
(VT_MASKCN GPR:$rs1, GPR:$rc)>;
|
||||
def : Pat<(select (riscv_seteq GPR:$rc), (i64 0), GPR:$rs1),
|
||||
(VT_MASKC GPR:$rs1, GPR:$rc)>;
|
||||
|
||||
// Conditional AND operation patterns.
|
||||
def : Pat<(i64 (select GPR:$rc, (and GPR:$rs1, GPR:$rs2), GPR:$rs1)),
|
||||
@ -49,30 +54,9 @@ def : Pat<(i64 (select GPR:$rc, GPR:$rs1, (and GPR:$rs1, GPR:$rs2))),
|
||||
def : Pat<(i64 (select GPR:$rc, GPR:$rs1, GPR:$rs2)),
|
||||
(OR (VT_MASKC $rs1, $rc), (VT_MASKCN $rs2, $rc))>;
|
||||
|
||||
def : Pat<(i64 (select (i64 (setne GPR:$rc, (i64 0))), GPR:$rs1, GPR:$rs2)),
|
||||
def : Pat<(i64 (select (riscv_setne GPR:$rc), GPR:$rs1, GPR:$rs2)),
|
||||
(OR (VT_MASKC GPR:$rs1, GPR:$rc), (VT_MASKCN GPR:$rs2, GPR:$rc))>;
|
||||
def : Pat<(i64 (select (i64 (seteq GPR:$rc, (i64 0))), GPR:$rs2, GPR:$rs1)),
|
||||
def : Pat<(i64 (select (riscv_seteq GPR:$rc), GPR:$rs2, GPR:$rs1)),
|
||||
(OR (VT_MASKC GPR:$rs1, GPR:$rc), (VT_MASKCN GPR:$rs2, GPR:$rc))>;
|
||||
|
||||
def : Pat<(i64 (select (i64 (setne GPR:$x, simm12_plus1:$y)), GPR:$rs1, GPR:$rs2)),
|
||||
(OR (VT_MASKC GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y))),
|
||||
(VT_MASKCN GPR:$rs2, (ADDI GPR:$x, (NegImm simm12_plus1:$y))))>;
|
||||
def : Pat<(i64 (select (i64 (seteq GPR:$x, simm12_plus1:$y)), GPR:$rs2, GPR:$rs1)),
|
||||
(OR (VT_MASKC GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y))),
|
||||
(VT_MASKCN GPR:$rs2, (ADDI GPR:$x, (NegImm simm12_plus1:$y))))>;
|
||||
|
||||
def : Pat<(i64 (select (i64 (setne GPR:$x, (i64 -2048))), GPR:$rs1, GPR:$rs2)),
|
||||
(OR (VT_MASKC GPR:$rs1, (XORI GPR:$x, -2048)),
|
||||
(VT_MASKCN GPR:$rs2, (XORI GPR:$x, -2048)))>;
|
||||
def : Pat<(i64 (select (i64 (seteq GPR:$x, (i64 -2048))), GPR:$rs2, GPR:$rs1)),
|
||||
(OR (VT_MASKC GPR:$rs1, (XORI GPR:$x, -2048)),
|
||||
(VT_MASKCN GPR:$rs2, (XORI GPR:$x, -2048)))>;
|
||||
|
||||
def : Pat<(i64 (select (i64 (setne GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs2)),
|
||||
(OR (VT_MASKC GPR:$rs1, (XOR GPR:$x, GPR:$y)),
|
||||
(VT_MASKCN GPR:$rs2, (XOR GPR:$x, GPR:$y)))>;
|
||||
def : Pat<(i64 (select (i64 (seteq GPR:$x, GPR:$y)), GPR:$rs2, GPR:$rs1)),
|
||||
(OR (VT_MASKC GPR:$rs1, (XOR GPR:$x, GPR:$y)),
|
||||
(VT_MASKCN GPR:$rs2, (XOR GPR:$x, GPR:$y)))>;
|
||||
|
||||
} // Predicates = [IsRV64, HasVendorXVentanaCondOps]
|
||||
|
Loading…
Reference in New Issue
Block a user