Skip to content

Commit

Permalink
[X86][SSE] Move unaryshuffle(xor(x,-1)) -> xor(unaryshuffle(x),-1) fo…
Browse files Browse the repository at this point in the history
…ld into helper. NFCI.

We should be able to extend this "canonicalizeShuffleWithBinOps" to handle more generic binop cases where either/both operands can be cheaply shuffled.
  • Loading branch information
RKSimon committed Feb 25, 2021
1 parent f0e4610 commit 8b82669
Showing 1 changed file with 32 additions and 23 deletions.
55 changes: 32 additions & 23 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -36925,6 +36925,36 @@ static SDValue combineCommutableSHUFP(SDValue N, MVT VT, const SDLoc &DL,
return SDValue();
}

// Canonicalize UNARYSHUFFLE(XOR(X,-1)) -> XOR(UNARYSHUFFLE(X),-1) to
// help expose the 'NOT' pattern further up the DAG.
// TODO: This might be beneficial for any binop with a 'splattable' operand.
static SDValue canonicalizeShuffleWithBinOps(SDValue N, SelectionDAG &DAG,
const SDLoc &DL) {
EVT ShuffleVT = N.getValueType();
unsigned Opc = N.getOpcode();
switch (Opc) {
case X86ISD::MOVDDUP:
case X86ISD::PSHUFD: {
SDValue N0 = N.getOperand(0);
if (N->isOnlyUserOf(N.getOperand(0).getNode())) {
if (SDValue Not = IsNOT(N0, DAG, /*OneUse*/ true)) {
Not = DAG.getBitcast(ShuffleVT, Not);
Not = Opc == X86ISD::MOVDDUP
? DAG.getNode(Opc, DL, ShuffleVT, Not)
: DAG.getNode(Opc, DL, ShuffleVT, Not, N.getOperand(1));
EVT IntVT = Not.getValueType().changeTypeToInteger();
SDValue AllOnes = DAG.getConstant(-1, DL, IntVT);
Not = DAG.getBitcast(IntVT, Not);
Not = DAG.getNode(ISD::XOR, DL, IntVT, Not, AllOnes);
return DAG.getBitcast(ShuffleVT, Not);
}
}
break;
}
}
return SDValue();
}

/// Attempt to fold vpermf128(op(),op()) -> op(vpermf128(),vpermf128()).
static SDValue canonicalizeLaneShuffleWithRepeatedOps(SDValue V,
SelectionDAG &DAG,
Expand Down Expand Up @@ -36989,29 +37019,8 @@ static SDValue combineTargetShuffle(SDValue N, SelectionDAG &DAG,
if (SDValue R = combineCommutableSHUFP(N, VT, DL, DAG))
return R;

// Canonicalize UNARYSHUFFLE(XOR(X,-1) -> XOR(UNARYSHUFFLE(X),-1) to
// help expose the 'NOT' pattern further up the DAG.
// TODO: This might be beneficial for any binop with a 'splattable' operand.
switch (Opcode) {
case X86ISD::MOVDDUP:
case X86ISD::PSHUFD: {
SDValue Src = N.getOperand(0);
if (Src.hasOneUse() && Src.getValueType() == VT) {
if (SDValue Not = IsNOT(Src, DAG, /*OneUse*/ true)) {
Not = DAG.getBitcast(VT, Not);
Not = Opcode == X86ISD::MOVDDUP
? DAG.getNode(Opcode, DL, VT, Not)
: DAG.getNode(Opcode, DL, VT, Not, N.getOperand(1));
EVT IntVT = Not.getValueType().changeTypeToInteger();
SDValue AllOnes = DAG.getConstant(-1, DL, IntVT);
Not = DAG.getBitcast(IntVT, Not);
Not = DAG.getNode(ISD::XOR, DL, IntVT, Not, AllOnes);
return DAG.getBitcast(VT, Not);
}
}
break;
}
}
if (SDValue R = canonicalizeShuffleWithBinOps(N, DAG, DL))
return R;

// Handle specific target shuffles.
switch (Opcode) {
Expand Down

0 comments on commit 8b82669

Please sign in to comment.