[llvm] [VPlan] Simplify (X && Y) || (X && !Y) -> X. (PR #89386)

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Tue May 14 03:54:50 PDT 2024


================
@@ -192,6 +191,47 @@ using AllBinaryRecipe_match =
     BinaryRecipe_match<Op0_t, Op1_t, Opcode, VPWidenRecipe, VPReplicateRecipe,
                        VPWidenCastRecipe, VPInstruction>;
 
+template <typename Op0_t, typename Op1_t, unsigned Opcode, bool Commutable,
+          typename... RecipeTys>
+struct LogicalRecipe_match {
+  Op0_t LHS;
+  Op1_t RHS;
+
+  LogicalRecipe_match(Op0_t LHS, Op1_t RHS) : LHS(LHS), RHS(RHS) {}
+
+  bool match(const VPValue *V) {
+    auto *DefR = V->getDefiningRecipe();
+    return DefR && match(DefR);
+  }
+
+  bool match(const VPSingleDefRecipe *R) {
+    return match(static_cast<const VPRecipeBase *>(R));
+  }
+
+  bool match(const VPRecipeBase *R) {
+    if (!detail::MatchRecipeAndOpcode<Opcode, RecipeTys...>::match(R)) {
+      if (!detail::MatchRecipeAndOpcode<Instruction::Select,
+                                        RecipeTys...>::match(R))
+        return false;
+      if (Opcode == Instruction::And) {
+        if (!m_False().match(R->getOperand(2)))
----------------
fhahn wrote:

Updated now to be based on LogicalAnd. 

> Perhaps Not should also become a LogicalNot, generating a select %c, false, true instead of the natural xor %c, true? 

I am not entirely sure about changing  the IR we generate here, the XOR variant appears to be the canonical for expected by other passes (i.e. that's what IRBuilder.CreateNot generates)

https://github.com/llvm/llvm-project/pull/89386


More information about the llvm-commits mailing list