[llvm] Fujun.han/instcombine or to xor (PR #75129)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 11 18:52:56 PST 2023


================
@@ -3343,6 +3343,27 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
   if (Instruction *X = foldComplexAndOrPatterns(I, Builder))
     return X;
 
+  // Change (or (and (add x, half_c1), c3), (and x, c2)) to (xor x, half_c1),
+  // iff c1, c2, c3 is constant, and half_c1 = (lshr c1, 1),  and c1 is pow2,
+  // and c2 < c1, and c3 == (c1 - 1) ^ c2, and (c1 >> 1) & c3 == (c1 >> 1) and x
+  // is known to be less than c1.
+  Type *Ty = I.getType();
+  if (Ty->isIntegerTy()) {
+    Value *X = nullptr;
+    const APInt *HalfC1 = nullptr, *C2 = nullptr, *C3 = nullptr;
+    if (match(&I,
+              m_c_Or(m_c_And(m_c_Add(m_Value(X), m_APInt(HalfC1)), m_APInt(C3)),
+                     m_c_And(m_Value(X), m_APInt(C2))))) {
+      const APInt C1 = HalfC1->shl(1);
+      KnownBits KnownX = computeKnownBits(X, 0, nullptr);
+      if (C1.isPowerOf2() && C2->ult(C1) && (*C3 == (*C2 ^ (C1 - 1))) &&
+          ((*HalfC1 & *C3) == *HalfC1) && KnownX.getMaxValue().ult(C1)) {
+        Value *Xor = Builder.CreateXor(X, ConstantInt::get(Ty, *HalfC1));
+        return replaceInstUsesWith(I, Xor);
----------------
dtcxzyw wrote:

```suggestion
        return BinaryOperator::CreateXor(X, ConstantInt::get(Ty, *HalfC1));
```

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


More information about the llvm-commits mailing list