Skip to content

Commit bf5748a

Browse files
committed
[x86] fold vector (X > -1) & Y to shift+andn
and (pcmpgt X, -1), Y --> pandn (vsrai X, BitWidth-1), Y This avoids the -1 constant vector in favor of an arithmetic shift instruction if it exists (the ISA is still not complete after all these years...). We catch this pattern late in combining by matching PCMPGT, so it should not interfere with more general folds. Differential Revision: https://reviews.llvm.org/D113603
1 parent ab6ef58 commit bf5748a

File tree

3 files changed

+208
-199
lines changed

3 files changed

+208
-199
lines changed

llvm/lib/Target/X86/X86ISelLowering.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45809,6 +45809,31 @@ static SDValue combineAndMaskToShift(SDNode *N, SelectionDAG &DAG,
4580945809
if (VT != Op1.getValueType() || !VT.isSimple() || !VT.isInteger())
4581045810
return SDValue();
4581145811

45812+
// Try to convert an "is positive" signbit masking operation into arithmetic
45813+
// shift and "andn". This saves a materialization of a -1 vector constant.
45814+
// The "is negative" variant should be handled more generally because it only
45815+
// requires "and" rather than "andn":
45816+
// and (pcmpgt X, -1), Y --> pandn (vsrai X, BitWidth - 1), Y
45817+
if (supportedVectorShiftWithImm(VT.getSimpleVT(), Subtarget, ISD::SRA)) {
45818+
SDValue X, Y;
45819+
if (Op1.hasOneUse() && Op1.getOpcode() == X86ISD::PCMPGT &&
45820+
isAllOnesOrAllOnesSplat(Op1.getOperand(1))) {
45821+
X = Op1.getOperand(0);
45822+
Y = Op0;
45823+
} else if (Op0.hasOneUse() && Op0.getOpcode() == X86ISD::PCMPGT &&
45824+
isAllOnesOrAllOnesSplat(Op0.getOperand(1))) {
45825+
X = Op0.getOperand(0);
45826+
Y = Op1;
45827+
}
45828+
if (X && Y) {
45829+
SDLoc DL(N);
45830+
SDValue Sra =
45831+
getTargetVShiftByConstNode(X86ISD::VSRAI, DL, VT.getSimpleVT(), X,
45832+
VT.getScalarSizeInBits() - 1, DAG);
45833+
return DAG.getNode(X86ISD::ANDNP, DL, VT, Sra, Y);
45834+
}
45835+
}
45836+
4581245837
APInt SplatVal;
4581345838
if (!ISD::isConstantSplatVector(Op1.getNode(), SplatVal) ||
4581445839
!SplatVal.isMask())

0 commit comments

Comments
 (0)