[Mips] Change vsplat_imm_eq_1 to a ComplexPattern. (#116471)

Resolves a FIXME and avoids needing to workaround #116075.

Adding parentheses around the (vsplat_imm_eq_1) fixes the error cited in
the FIXME by changing the ComplexPattern from a leaf node to an
operator.
This commit is contained in:
Craig Topper
2024-11-16 20:55:33 -08:00
committed by GitHub
parent ddc0eb70c8
commit 2f4572f5e7
5 changed files with 43 additions and 38 deletions

View File

@@ -175,6 +175,10 @@ bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
return false;
}
bool MipsDAGToDAGISel::selectVSplatImmEq1(SDValue N) const {
llvm_unreachable("Unimplemented function.");
}
/// Convert vector addition with vector subtraction if that allows to encode
/// constant as an immediate and thus avoid extra 'ldi' instruction.
/// add X, <-1, -1...> --> sub X, <1, 1...>

View File

@@ -116,6 +116,9 @@ private:
/// starting at bit zero.
virtual bool selectVSplatMaskR(SDValue N, SDValue &Imm) const;
/// Select constant vector splats whose value is 1.
virtual bool selectVSplatImmEq1(SDValue N) const;
/// Convert vector addition with vector subtraction if that allows to encode
/// constant as an immediate and thus avoid extra 'ldi' instruction.
/// add X, <-1, -1...> --> sub X, <1, 1...>

View File

@@ -198,14 +198,8 @@ def vsplati32 : PatFrag<(ops node:$e0),
(v4i32 (build_vector node:$e0, node:$e0,
node:$e0, node:$e0))>;
def vsplati64_imm_eq_1 : PatLeaf<(bitconvert (v4i32 (build_vector))), [{
APInt Imm;
SDNode *BV = N->getOperand(0).getNode();
EVT EltTy = N->getValueType(0).getVectorElementType();
return selectVSplat(BV, Imm, EltTy.getSizeInBits()) &&
Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1;
}]>;
// Any build_vector that is a constant splat with a value that equals 1
def vsplat_imm_eq_1 : ComplexPattern<vAny, 0, "selectVSplatImmEq1">;
def vsplati64 : PatFrag<(ops node:$e0),
(v2i64 (build_vector node:$e0, node:$e0))>;
@@ -217,7 +211,7 @@ def vsplati64_splat_d : PatFrag<(ops node:$e0),
node:$e0,
node:$e0,
node:$e0)),
vsplati64_imm_eq_1))))>;
(vsplat_imm_eq_1)))))>;
def vsplatf32 : PatFrag<(ops node:$e0),
(v4f32 (build_vector node:$e0, node:$e0,
@@ -352,46 +346,35 @@ def vsplat_maskr_bits_uimm6
: SplatComplexPattern<vsplat_uimm6, vAny, 1, "selectVSplatMaskR",
[build_vector, bitconvert]>;
// Any build_vector that is a constant splat with a value that equals 1
// FIXME: These should be a ComplexPattern but we can't use them because the
// ISel generator requires the uses to have a name, but providing a name
// causes other errors ("used in pattern but not operand list")
def vsplat_imm_eq_1 : PatLeaf<(build_vector), [{
APInt Imm;
EVT EltTy = N->getValueType(0).getVectorElementType();
return selectVSplat(N, Imm, EltTy.getSizeInBits()) &&
Imm.getBitWidth() == EltTy.getSizeInBits() && Imm == 1;
}]>;
def vbclr_b : PatFrag<(ops node:$ws, node:$wt),
(and node:$ws, (vnot (shl vsplat_imm_eq_1, node:$wt)))>;
(and node:$ws, (vnot (shl (vsplat_imm_eq_1), node:$wt)))>;
def vbclr_h : PatFrag<(ops node:$ws, node:$wt),
(and node:$ws, (vnot (shl vsplat_imm_eq_1, node:$wt)))>;
(and node:$ws, (vnot (shl (vsplat_imm_eq_1), node:$wt)))>;
def vbclr_w : PatFrag<(ops node:$ws, node:$wt),
(and node:$ws, (vnot (shl vsplat_imm_eq_1, node:$wt)))>;
(and node:$ws, (vnot (shl (vsplat_imm_eq_1), node:$wt)))>;
def vbclr_d : PatFrag<(ops node:$ws, node:$wt),
(and node:$ws, (vnot (shl (v2i64 vsplati64_imm_eq_1),
(and node:$ws, (vnot (shl (v2i64 (vsplat_imm_eq_1)),
node:$wt)))>;
def vbneg_b : PatFrag<(ops node:$ws, node:$wt),
(xor node:$ws, (shl vsplat_imm_eq_1, node:$wt))>;
(xor node:$ws, (shl (vsplat_imm_eq_1), node:$wt))>;
def vbneg_h : PatFrag<(ops node:$ws, node:$wt),
(xor node:$ws, (shl vsplat_imm_eq_1, node:$wt))>;
(xor node:$ws, (shl (vsplat_imm_eq_1), node:$wt))>;
def vbneg_w : PatFrag<(ops node:$ws, node:$wt),
(xor node:$ws, (shl vsplat_imm_eq_1, node:$wt))>;
(xor node:$ws, (shl (vsplat_imm_eq_1), node:$wt))>;
def vbneg_d : PatFrag<(ops node:$ws, node:$wt),
(xor node:$ws, (shl (v2i64 vsplati64_imm_eq_1),
(xor node:$ws, (shl (v2i64 (vsplat_imm_eq_1)),
node:$wt))>;
def vbset_b : PatFrag<(ops node:$ws, node:$wt),
(or node:$ws, (shl vsplat_imm_eq_1, node:$wt))>;
(or node:$ws, (shl (vsplat_imm_eq_1), node:$wt))>;
def vbset_h : PatFrag<(ops node:$ws, node:$wt),
(or node:$ws, (shl vsplat_imm_eq_1, node:$wt))>;
(or node:$ws, (shl (vsplat_imm_eq_1), node:$wt))>;
def vbset_w : PatFrag<(ops node:$ws, node:$wt),
(or node:$ws, (shl vsplat_imm_eq_1, node:$wt))>;
(or node:$ws, (shl (vsplat_imm_eq_1), node:$wt))>;
def vbset_d : PatFrag<(ops node:$ws, node:$wt),
(or node:$ws, (shl (v2i64 vsplati64_imm_eq_1),
(or node:$ws, (shl (v2i64 (vsplat_imm_eq_1)),
node:$wt))>;
def muladd : PatFrag<(ops node:$wd, node:$ws, node:$wt),
@@ -3842,7 +3825,7 @@ class MSAShiftPat<SDNode Node, ValueType VT, MSAInst Insn, dag Vec> :
(VT (Insn VT:$ws, VT:$wt))>;
class MSABitPat<SDNode Node, ValueType VT, MSAInst Insn, PatFrag Frag> :
MSAPat<(VT (Node VT:$ws, (shl vsplat_imm_eq_1, (Frag VT:$wt)))),
MSAPat<(VT (Node VT:$ws, (shl (vsplat_imm_eq_1), (Frag VT:$wt)))),
(VT (Insn VT:$ws, VT:$wt))>;
multiclass MSAShiftPats<SDNode Node, string Insn> {
@@ -3861,7 +3844,7 @@ multiclass MSABitPats<SDNode Node, string Insn> {
def : MSABitPat<Node, v16i8, !cast<MSAInst>(Insn#_B), vsplati8imm7>;
def : MSABitPat<Node, v8i16, !cast<MSAInst>(Insn#_H), vsplati16imm15>;
def : MSABitPat<Node, v4i32, !cast<MSAInst>(Insn#_W), vsplati32imm31>;
def : MSAPat<(Node v2i64:$ws, (shl (v2i64 vsplati64_imm_eq_1),
def : MSAPat<(Node v2i64:$ws, (shl (v2i64 (vsplat_imm_eq_1)),
(vsplati64imm63 v2i64:$wt))),
(v2i64 (!cast<MSAInst>(Insn#_D) v2i64:$ws, v2i64:$wt))>;
}
@@ -3872,16 +3855,16 @@ defm : MSAShiftPats<sra, "SRA">;
defm : MSABitPats<xor, "BNEG">;
defm : MSABitPats<or, "BSET">;
def : MSAPat<(and v16i8:$ws, (vnot (shl vsplat_imm_eq_1,
def : MSAPat<(and v16i8:$ws, (vnot (shl (vsplat_imm_eq_1),
(vsplati8imm7 v16i8:$wt)))),
(v16i8 (BCLR_B v16i8:$ws, v16i8:$wt))>;
def : MSAPat<(and v8i16:$ws, (vnot (shl vsplat_imm_eq_1,
def : MSAPat<(and v8i16:$ws, (vnot (shl (vsplat_imm_eq_1),
(vsplati16imm15 v8i16:$wt)))),
(v8i16 (BCLR_H v8i16:$ws, v8i16:$wt))>;
def : MSAPat<(and v4i32:$ws, (vnot (shl vsplat_imm_eq_1,
def : MSAPat<(and v4i32:$ws, (vnot (shl (vsplat_imm_eq_1),
(vsplati32imm31 v4i32:$wt)))),
(v4i32 (BCLR_W v4i32:$ws, v4i32:$wt))>;
def : MSAPat<(and v2i64:$ws, (vnot (shl (v2i64 vsplati64_imm_eq_1),
def : MSAPat<(and v2i64:$ws, (vnot (shl (v2i64 (vsplat_imm_eq_1)),
(vsplati64imm63 v2i64:$wt)))),
(v2i64 (BCLR_D v2i64:$ws, v2i64:$wt))>;

View File

@@ -679,6 +679,18 @@ bool MipsSEDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N,
return false;
}
// Select const vector splat of 1.
bool MipsSEDAGToDAGISel::selectVSplatImmEq1(SDValue N) const {
APInt ImmValue;
EVT EltTy = N->getValueType(0).getVectorElementType();
if (N->getOpcode() == ISD::BITCAST)
N = N->getOperand(0);
return selectVSplat(N.getNode(), ImmValue, EltTy.getSizeInBits()) &&
ImmValue.getBitWidth() == EltTy.getSizeInBits() && ImmValue == 1;
}
bool MipsSEDAGToDAGISel::trySelect(SDNode *Node) {
unsigned Opcode = Node->getOpcode();
SDLoc DL(Node);

View File

@@ -108,6 +108,9 @@ private:
/// starting at bit zero.
bool selectVSplatMaskR(SDValue N, SDValue &Imm) const override;
/// Select constant vector splats whose value is 1.
bool selectVSplatImmEq1(SDValue N) const override;
bool trySelect(SDNode *Node) override;
// Emits proper ABI for _mcount profiling calls.