[llvm] [InstCombine] Fold xored one-complemented operand comparisons (PR #69882)

via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 22 10:06:33 PDT 2023


================
@@ -7127,6 +7144,18 @@ Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) {
       return new ICmpInst(I.getInversePredicate(), Builder.CreateAnd(A, B),
                           Op1);
 
+    // Transform (~A ^ B) s< ~A --> (A ^ B) s> A,
+    //           (~A ^ B) s> ~A --> (A ^ B) s< A,
+    //           (~A ^ B) s<= ~A --> (A ^ B) s>= A,
+    //           (~A ^ B) s>= ~A --> (A ^ B) s<= A,
+    //           (~A ^ B) u< ~A --> (A ^ B) u< A,
+    //           (~A ^ B) u> ~A --> (A ^ B) u< A,
+    //           (~A ^ B) u<= ~A --> (A ^ B) u>= A,
+    // and       (~A ^ B) u>= ~A --> (A ^ B) <= A
+    if (match(Op0, m_Xor(m_Not(m_Value(A)), m_Value(B))) &&
+        match(Op1, m_Not(m_Value(A))) && !I.isEquality())
----------------
goldsteinn wrote:

1) You are overwriting `A` with the `m_Not` match. If you want to match the same `A` from the `xor` you would use `m_Specific(A)`.

2) You don't actually need `~A ^ B pred ~A`. You can do `~A ^ B pred ~C`:
https://alive2.llvm.org/ce/z/m8-MhQ

So the match on `Op1` should be setting a new value.

3) The match on `xor` should be commutative i.e it doesn't matter if its `~A ^ B` or `A ^ ~B`. so the match should be: `m_c_Xor(m_Not(A), B)`

4) This should work if `Op1` is the `m_Not` and `Op0` is the `m_Xor` so I would do a commutative match along the lines of:
`if(match(&I, m_c_ICmp(Pred, m_c_Xor(m_Not(m_Value(A)), m_Value(B)), m_Not(m_Value(C)))`.

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


More information about the llvm-commits mailing list