[llvm] [InstCombine] Fold (X << Y) / (X << Z) -> 1 << Y >> Z (PR #68863)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 12 04:41:45 PDT 2023


================
@@ -980,6 +980,28 @@ static Instruction *foldIDivShl(BinaryOperator &I,
       Ret = BinaryOperator::CreateSDiv(X, Y);
   }
 
+  // If X << Y and X << Z does not overflow, then:
+  // (X << Y) / (X << Z) -> (1 << Y) / (1 << Z) -> 1 << Y >> Z
+  // Ignore it when X == 1, to avoid infinite loop.
+  // Only when both Op0 and Op1 have uses, this fold produces one extra
+  // instruction.
+  if (match(Op0, m_Shl(m_Value(X), m_Value(Y))) &&
+      match(Op1, m_Shl(m_Specific(X), m_Value(Z))) && !(match(X, m_One())) &&
----------------
dtcxzyw wrote:

```suggestion
  // Only when both Op0 and Op1 have uses, this fold produces one extra
  // instruction.
  if (match(Op0, m_Shl(m_Value(X), m_Value(Y))) &&
      match(Op1, m_Shl(m_Specific(X), m_Value(Z))) &&
```
Please also remove duplicate logic that folds `(1 << Y) / (1 << Z) -> 1 << Y >> Z`.


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


More information about the llvm-commits mailing list