Skip to content

[Mips] Change vsplat_imm_eq_1 to a ComplexPattern. #116471

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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...>
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Mips/MipsISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,9 @@ class MipsDAGToDAGISel : public SelectionDAGISel {
/// 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...>
Expand Down
59 changes: 21 additions & 38 deletions llvm/lib/Target/Mips/MipsMSAInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -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))>;
Expand All @@ -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,
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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> {
Expand All @@ -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))>;
}
Expand All @@ -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))>;

Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ class MipsSEDAGToDAGISel : public MipsDAGToDAGISel {
/// 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.
Expand Down
Loading