[llvm] [X86][AVX] Fix handling of out-of-bounds shift amounts in AVX2 vector logical shift nodes #83840 (PR #86922)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Thu May 2 09:50:56 PDT 2024
================
@@ -45612,6 +45612,30 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
}
}
+ // Exploits AVX2 VSHLV/VSRLV instructions for efficient unsigned vector shifts
+ // with out-of-bounds clamping.
+
+ // Unlike general shift instructions (SHL/SRL), AVX2's VSHLV/VSRLV handle
+ // shift amounts exceeding the element bitwidth. VSHLV clamps the amount to
+ // bitwidth-1 for unsigned shifts, effectively performing a maximum left shift
+ // of bitwidth-1 positions. Similarly, VSRLV returns zero for unsigned shifts
+ // exceeding bitwidth-1, achieving a maximum right shift of bitwidth-1.
+ if (N->getOpcode() == ISD::VSELECT &&
+ (LHS.getOpcode() == ISD::SRL || LHS.getOpcode() == ISD::SHL) &&
+ supportedVectorVarShift(VT, Subtarget, LHS.getOpcode())) {
+ APInt SV;
+ if (Cond.getOpcode() == ISD::SETCC &&
+ Cond.getOperand(0) == LHS.getOperand(1) &&
+ cast<CondCodeSDNode>(Cond.getOperand(2))->get() == ISD::SETULT &&
+ ISD::isConstantSplatVector(Cond.getOperand(1).getNode(), SV) &&
+ ISD::isConstantSplatVectorAllZeros(RHS.getNode()) &&
+ SV == VT.getScalarSizeInBits()) {
+ return DAG.getNode(
+ LHS.getOpcode() == ISD::SRL ? X86ISD::VSRLV : X86ISD::VSHLV, DL,
+ LHS->getVTList(), LHS.getOperand(0), LHS.getOperand(1));
----------------
RKSimon wrote:
LHS->getVTList() can be replaced with VT
https://github.com/llvm/llvm-project/pull/86922
More information about the llvm-commits
mailing list