[llvm] [DAG] Refactor X86 combineVSelectWithAllOnesOrZeros fold into a generic DAG Combine (PR #145298)
Simon Pilgrim via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 25 02:58:00 PDT 2025
================
@@ -12945,6 +12945,85 @@ 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!");
+
+ // Classify TVal/FVal content
+ 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);
+ }
+
+ // 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();
+
+ // 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);
----------------
RKSimon wrote:
Can we avoid this if we're not going to fold? Creating unused nodes mid-fold like this can cause problems with oneuse folds later on.
https://github.com/llvm/llvm-project/pull/145298
More information about the llvm-commits
mailing list