Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -14513,9 +14513,10 @@ return SDValue(); // Restricted the DAG combine to only cases where we're extracting from a - // flag-setting operation - auto *Idx = dyn_cast(N->getOperand(1)); - if (!Idx || !Idx->isZero() || SetCC.getOpcode() != ISD::SETCC) + // flag-setting operation. + if (!isNullConstant(N->getOperand(1)) || + (SetCC.getOpcode() != ISD::SETCC && + SetCC.getOpcode() != ISD::INTRINSIC_WO_CHAIN)) return SDValue(); // Extracts of lane 0 for SVE can be expressed as PTEST(Op, FIRST) ? 1 : 0 Index: llvm/test/CodeGen/AArch64/sve-cmp-folds.ll =================================================================== --- llvm/test/CodeGen/AArch64/sve-cmp-folds.ll +++ llvm/test/CodeGen/AArch64/sve-cmp-folds.ll @@ -30,5 +30,16 @@ ret i1 %bit } +define i1 @whilelo_first(i64 %next, i64 %end) { +; CHECK-LABEL: whilelo_first: +; CHECK: // %bb.0: +; CHECK-NEXT: whilelo p0.s, x0, x1 +; CHECK-NEXT: cset w0, mi +; CHECK-NEXT: ret + %predicate = call @llvm.aarch64.sve.whilelo.nxv4i1.i64(i64 %next, i64 %end) + %bit = extractelement %predicate, i64 0 + ret i1 %bit +} declare i64 @llvm.vscale.i64() +declare @llvm.aarch64.sve.whilelo.nxv4i1.i64(i64, i64)