[PATCH] D143283: [Transform][InstCombine]: transform lshr pattern.

hassnaaHamdi via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 3 09:57:05 PST 2023


hassnaa-arm created this revision.
hassnaa-arm added reviewers: david-arm, sdesmalen.
Herald added a subscriber: hiraditya.
Herald added a project: All.
hassnaa-arm requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Transform lshr Op0, Op1
 where Op0: Add(X, Z),
 X = Add(A, B).
To:
 when Z=0: lshr(A,1) + lshr(B,1) + (A&B)&1
 when Z=1: lshr(A,1) + lshr(B,1) + (A|B)&1

That pattern matches the case of: (A+b+0) >>=1 which is transformed to: (A>>1)+(B>>1)+(A&B)&1
or: (A+b+1) >>=1 which is transformed to: (A>>1)+(B>>1)+(A|B)&1


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D143283

Files:
  llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp


Index: llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1411,6 +1411,56 @@
     }
   }
 
+  // lshr (add(add(A, B), 1), 1)
+  // -->
+  // (A >> 1) + (B >> 1) + (A|B)&1
+
+  // lshr (add(add(A, B), 0), 1)
+  // -->
+  // (A >> 1) + (B >> 1) + (A&B)&1
+  if (match(Op1, m_APInt(C))) {
+    unsigned ShAmtC = C->getZExtValue();
+    if(1 == ShAmtC) {
+      const APInt *constantInt = nullptr;
+      // Op0: add (X, 1)
+      if(match(Op0,
+                  m_Add(m_OneUse(m_Value(X)), m_APInt(constantInt)))) {
+        unsigned constAmt = constantInt->getZExtValue();
+        // constAmt = 1 | 0
+        if(constAmt <= 1) {
+          Value *A = nullptr, *B = nullptr;
+          // X: add(A, B)
+          if(match(X,
+                    m_Add(m_OneUse(m_Value(A)), m_OneUse(m_Value(B))))) {
+            // (A >> 1)
+            Value *ALshr = Builder.CreateLShr(A, Op1);
+            // (B >> 1)
+            Value *BLshr = Builder.CreateLShr(B, Op1);
+
+            APInt Bits = APInt::getLowBitsSet(BitWidth, 1);
+            Constant *Mask = ConstantInt::get(Ty, Bits);
+            Value *AB = nullptr;
+
+            if(0 == constAmt) {
+              // (A&B)
+              AB = Builder.CreateAnd(A, B);
+            }
+            else {
+              // (A|B)
+              AB = Builder.CreateOr(A, B);
+            }
+            // AB&1
+            Value *AB1 = Builder.CreateAnd(AB, Mask);
+            // final step: ALshr + BLshr + AB1
+            Value *Add1 = Builder.CreateAdd(ALshr, BLshr);
+            auto *newInstr = BinaryOperator::CreateAdd(Add1, AB1);
+            return newInstr;
+          }
+        }
+      }
+    }
+  }
+
   // Transform  (x << y) >> y  to  x & (-1 >> y)
   if (match(Op0, m_OneUse(m_Shl(m_Value(X), m_Specific(Op1))))) {
     Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D143283.494676.patch
Type: text/x-patch
Size: 2035 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230203/1f15512b/attachment.bin>


More information about the llvm-commits mailing list