[llvm] [DAG] Refactor X86 combineVSelectWithAllOnesOrZeros fold into a generic DAG Combine (PR #145298)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 27 07:13:45 PDT 2025
================
@@ -13069,6 +13069,96 @@ SDValue DAGCombiner::visitVP_SELECT(SDNode *N) {
return SDValue();
}
+static SDValue combineVSelectWithAllOnesOrZeros(SDValue Cond, SDValue TVal,
+ SDValue FVal,
+ const TargetLowering &TLI,
+ SelectionDAG &DAG,
+ const SDLoc &DL) {
+ if (!TLI.isTypeLegal(TVal.getValueType()))
+ return SDValue();
+
+ EVT VT = TVal.getValueType();
+ EVT CondVT = Cond.getValueType();
+
+ assert(CondVT.isVector() && "Vector select expects a vector selector!");
+
+ bool IsTAllZero = ISD::isBuildVectorAllZeros(TVal.getNode());
+ bool IsTAllOne = ISD::isBuildVectorAllOnes(TVal.getNode());
+ bool IsFAllZero = ISD::isBuildVectorAllZeros(FVal.getNode());
+ bool IsFAllOne = ISD::isBuildVectorAllOnes(FVal.getNode());
+
+ // no vselect(cond, 0/-1, X) or vselect(cond, X, 0/-1), return
+ if (!IsTAllZero && !IsTAllOne && !IsFAllZero && !IsFAllOne)
+ return SDValue();
+
+ // select Cond, 0, 0 → 0
+ if (IsTAllZero && IsFAllZero) {
+ return VT.isFloatingPoint() ? DAG.getConstantFP(0.0, DL, VT)
+ : DAG.getConstant(0, DL, VT);
+ }
+
+ // check select(setgt lhs, -1), 1, -1 --> or (sra lhs, bitwidth - 1), 1
+ APInt TValAPInt;
+ if (Cond.getOpcode() == ISD::SETCC &&
+ Cond.getOperand(2) == DAG.getCondCode(ISD::SETGT) &&
+ Cond.getOperand(0).getValueType() == VT && VT.isSimple() &&
+ ISD::isConstantSplatVector(TVal.getNode(), TValAPInt) &&
+ TValAPInt.isOne() &&
+ ISD::isConstantSplatVectorAllOnes(Cond.getOperand(1).getNode()) &&
+ ISD::isConstantSplatVectorAllOnes(FVal.getNode())) {
+ return SDValue();
+ }
+
+ // To use the condition operand as a bitwise mask, it must have elements that
+ // are the same size as the select elements. Ie, the condition operand must
+ // have already been promoted from the IR select condition type <N x i1>.
+ // Don't check if the types themselves are equal because that excludes
+ // vector floating-point selects.
+ if (CondVT.getScalarSizeInBits() != VT.getScalarSizeInBits())
+ return SDValue();
+
+ // Cond value must be 'sign splat' to be converted to a logical op.
+ if (DAG.ComputeNumSignBits(Cond) != CondVT.getScalarSizeInBits())
+ return SDValue();
+
+ // Try inverting Cond and swapping T/F if it gives all-ones/all-zeros form
+ if (!IsTAllOne && !IsFAllZero && Cond.hasOneUse() &&
+ Cond.getOpcode() == ISD::SETCC &&
+ TLI.getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT) ==
+ CondVT) {
+ if (IsTAllZero || IsFAllOne) {
+ SDValue CC = Cond.getOperand(2);
+ ISD::CondCode InverseCC = ISD::getSetCCInverse(
+ cast<CondCodeSDNode>(CC)->get(), Cond.getOperand(0).getValueType());
+ Cond = DAG.getSetCC(DL, CondVT, Cond.getOperand(0), Cond.getOperand(1),
+ InverseCC);
+ std::swap(TVal, FVal);
+ std::swap(IsTAllOne, IsFAllOne);
+ std::swap(IsTAllZero, IsFAllZero);
----------------
woruyu wrote:
OK, i will add it
https://github.com/llvm/llvm-project/pull/145298
More information about the llvm-commits
mailing list