Skip to content

Commit

Permalink
[X86] Fold (movmsk (setne (and X, (1 << C)), 0)) -> (movmsk (X << C))
Browse files Browse the repository at this point in the history
Summary:
MOVMSK only care about the sign bit so we don't need the setcc to fill the whole element with 0s/1s. We can just shift the bit we're looking for into the sign bit. This saves a constant pool load.

Inspired by PR38840.

Reviewers: RKSimon, spatel

Reviewed By: RKSimon

Subscribers: lebedev.ri, llvm-commits

Differential Revision: https://reviews.llvm.org/D52121

llvm-svn: 342326
  • Loading branch information
topperc committed Sep 15, 2018
1 parent 7513419 commit 273f755
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 220 deletions.
26 changes: 26 additions & 0 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Expand Up @@ -38812,6 +38812,32 @@ static SDValue combineMOVMSK(SDNode *N, SelectionDAG &DAG,
return SDValue(N, 0);
}

// Combine (movmsk (setne (and X, (1 << C)), 0)) -> (movmsk (X << C)).
// Only do this when the setcc input and output types are the same and the
// setcc and the 'and' node have a single use.
// FIXME: Support i8 shifts. The lowering produces an extra and.
// FIXME: Support 256-bits with AVX1. The movmsk is split, but the and isn't.
APInt SplatVal;
if (Src.getOpcode() == ISD::SETCC && Src.hasOneUse() &&
Src.getOperand(0).getValueType() == Src.getValueType() &&
Src.getValueType().getScalarSizeInBits() >= 32 &&
cast<CondCodeSDNode>(Src.getOperand(2))->get() == ISD::SETNE &&
ISD::isBuildVectorAllZeros(Src.getOperand(1).getNode())) {
SDValue In = Src.getOperand(0);
if (In.getOpcode() == ISD::AND && In.hasOneUse() &&
ISD::isConstantSplatVector(In.getOperand(1).getNode(), SplatVal) &&
SplatVal.isPowerOf2()) {
MVT VT = Src.getSimpleValueType();
unsigned BitWidth = VT.getScalarSizeInBits();
unsigned ShAmt = BitWidth - SplatVal.logBase2() - 1;
SDLoc DL(Src.getOperand(0));
SDValue Shl = DAG.getNode(ISD::SHL, DL, VT, In.getOperand(0),
DAG.getConstant(ShAmt, DL, VT));
SDValue Cast = DAG.getBitcast(SrcVT, Shl);
return DAG.getNode(X86ISD::MOVMSK, SDLoc(N), N->getValueType(0), Cast);
}
}

return SDValue();
}

Expand Down

0 comments on commit 273f755

Please sign in to comment.