[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:
@@ -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...>
|
||||
|
||||
@@ -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...>
|
||||
|
||||
@@ -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))>;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user