[PATCH] D147266: [AArch64] Sink operands to allow for bitselect instructions

Pranav Kant via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu May 11 15:28:25 PDT 2023


pranavk updated this revision to Diff 521474.
pranavk edited the summary of this revision.
pranavk added a comment.

Address reviewer comments


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147266/new/

https://reviews.llvm.org/D147266

Files:
  llvm/lib/Target/AArch64/AArch64ISelLowering.cpp


Index: llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -14332,6 +14332,48 @@
 
     return true;
   }
+  case Instruction::Or: {
+    // Pattern: Or(And(MaskValue, A), And(Not(MaskValue), B)) ->
+    // bitselect(MaskValue, A, B) where Not(MaskValue) = Xor(MaskValue, -1)
+    if (Subtarget->hasNEON()) {
+      // If any of the intermediate Ands have uses other than Or, don't fold
+      if (!I->getOperand(0)->hasOneUse() || !I->getOperand(0)->hasOneUse())
+        return false;
+
+      Instruction *OtherAnd, *IA, *IB;
+      Value *MaskValue;
+      // MainAnd refers to And instruction that has 'Not' as one of its operands
+      if (match(I, m_c_Or(m_Instruction(OtherAnd),
+                          m_c_And(m_Not(m_Value(MaskValue)),
+                                  m_Instruction(IA))))) {
+        if (match(OtherAnd,
+                  m_c_And(m_Specific(MaskValue), m_Instruction(IB)))) {
+          Instruction *MainAnd = I->getOperand(0) == OtherAnd
+                                     ? cast<Instruction>(I->getOperand(1))
+                                     : cast<Instruction>(I->getOperand(0));
+
+          // Both Ands should be in same basic block as Or
+          if (I->getParent() != MainAnd->getParent() ||
+              I->getParent() != OtherAnd->getParent())
+            return false;
+
+          // Non-mask operands of both Ands should also be in same basic block
+          if (I->getParent() != IA->getParent() ||
+              I->getParent() != IB->getParent())
+            return false;
+
+          Ops.push_back(&MainAnd->getOperandUse(0));
+          Ops.push_back(&MainAnd->getOperandUse(1));
+          Ops.push_back(&I->getOperandUse(0));
+          Ops.push_back(&I->getOperandUse(1));
+
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
   case Instruction::Mul: {
     int NumZExts = 0, NumSExts = 0;
     for (auto &Op : I->operands()) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D147266.521474.patch
Type: text/x-patch
Size: 2099 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230511/2e8c6392/attachment.bin>


More information about the cfe-commits mailing list