[llvm] [AArch64][InstCombine] Fold zext cmpne umin boolean trees (PR #209234)
Kerry McLaughlin via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 20 08:47:48 PDT 2026
================
@@ -2205,6 +2205,69 @@ static std::optional<Instruction *> instCombineZExtSVECmpNE(InstCombiner &IC,
return std::nullopt;
}
+static std::optional<Instruction *> isZextedCmpneUMin(Value *V) {
+ Instruction *CmpNE;
+ if (!match(V, m_ZExt(m_Instruction(CmpNE))))
+ return std::nullopt;
+
+ Value *Pg;
+ Instruction *UMin;
+ if (!match(CmpNE, m_Intrinsic<Intrinsic::aarch64_sve_cmpne>(
+ m_Value(Pg), m_Zero(), m_Instruction(UMin))) ||
+ !isAllActivePredicate(Pg) || V->getType() != UMin->getType())
+ return std::nullopt;
+
+ Value *UMinPg;
+ if (!match(UMin, m_Intrinsic<Intrinsic::aarch64_sve_umin_u>(
+ m_Value(UMinPg), m_Value(), m_Value())) ||
+ !isAllActivePredicate(UMinPg))
+ return std::nullopt;
+
+ return UMin;
+}
+
+// InstCombine:
+// zext(cmpne(0, umin(zext(cmpne(0, umin(%a, %b)))
+// zext(cmpne(0, umin(%c, %d))))))
+// ->
+// zext(cmpne(0, umin(umin(%a, %b),
+// umin(%c, %d))))
+//
+// To remove redundant ZExt and CmpNE intrinsics.
+static std::optional<Instruction *>
+instCombineZExtCmpNEUMinTree(InstCombiner &IC, IntrinsicInst &II) {
+ Value *Pg = II.getOperand(0);
+ if (!isAllActivePredicate(Pg) || !II.hasOneUse())
+ return std::nullopt;
+
+ auto ZExt = cast<Instruction>(*II.user_begin());
+ auto _UMin = isZextedCmpneUMin(ZExt);
+ if (!_UMin)
+ return std::nullopt;
+ Instruction *UMin = *_UMin;
+ // Check for outer UMin single use to avoid generating an extra UMin
+ if (!UMin->hasOneUse())
+ return std::nullopt;
----------------
kmclaughlin-arm wrote:
It looks like that might be because results from similar functions are then returned by `instCombineIntrinsic` (which also returns `std::optional<Instruction *>`), and that's not the case here?
https://github.com/llvm/llvm-project/pull/209234
More information about the llvm-commits
mailing list