[llvm] [SDAG][AArch64] Fold extract from pext to use status flags (PR #206443)
Gaƫtan Bossu via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 1 01:08:07 PDT 2026
================
@@ -21970,6 +21970,65 @@ performExtractLastActiveCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
Vec);
}
+static bool hasSVE2p1OrStreamingSME2(const AArch64Subtarget *Subtarget) {
+ return (Subtarget->isSVEorStreamingSVEAvailable() &&
+ Subtarget->hasSVE2p1()) ||
+ (Subtarget->isStreaming() && Subtarget->hasSME2());
+}
+
+static auto m_PredicateAsCounterWhile() {
+ using namespace llvm::SDPatternMatch;
+ return m_AnyOf(m_SpecificOpc(AArch64ISD::WHILEGE_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILEGT_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILELT_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILELE_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILEHS_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILEHI_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILELO_PRED_COUNTER),
+ m_SpecificOpc(AArch64ISD::WHILELS_PRED_COUNTER));
+}
+
+/// Folds extracting the first lane from the first segment of a
+/// predicate-as-counter while to a conditional set (CSET) based on the
+/// "FIRST_ACTIVE" status flag from the while.
+///
+/// %while = WHILE_*_PRED_COUNTER .. ; predicate-as-counter while
+/// %first.segment = pext(%while, 0) ; predicate extract of segment 0
+/// %first.active = extract_elt(%first_segment, 0) ; extract first lane
+///
+/// ->
+///
+/// %while = WHILE_*_PRED_COUNTER .. ; predicate-as-counter while
+/// %first.active = cset(%while, FIRST_ACTIVE)
+static SDValue
+perfomPextFirstTrueVectorCombine(SDNode *N,
+ TargetLowering::DAGCombinerInfo &DCI,
+ const AArch64Subtarget *Subtarget) {
+ using namespace llvm::SDPatternMatch;
+ assert(N->getOpcode() == ISD::EXTRACT_VECTOR_ELT);
+ if (DCI.isBeforeLegalize() || !hasSVE2p1OrStreamingSME2(Subtarget))
+ return SDValue();
+
+ SDValue N0 = N->getOperand(0);
+ EVT VT = N0.getValueType();
+
+ if (!VT.isScalableVectorOf(MVT::i1) || !isNullConstant(N->getOperand(1)))
+ return SDValue();
+
+ SelectionDAG &DAG = DCI.DAG;
+
+ // Fold: extract_elt(pext(WHILE_*_PRED_COUNTER, 0), 0)
+ // to cset(WHILE_*_PRED_COUNTER, FIRST_ACTIVE).
----------------
gbossu wrote:
Nit: `cset(WHILE_*_PRED_COUNTER:1, FIRST_ACTIVE)`
https://github.com/llvm/llvm-project/pull/206443
More information about the llvm-commits
mailing list