This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Improve transforms for (icmp uPred X * Z, Y * Z) -> (icmp uPred X, Y)
ClosedPublic

Authored by goldstein.w.n on Jan 27 2023, 3:25 PM.

Details

Summary

Several cases where missing.

  1. (icmp eq/ne X*Z, Y*Z) [if Z % 2 != 0] -> (icmp eq/ne X, Y) EQ: https://alive2.llvm.org/ce/z/6_HPZ5 NE: https://alive2.llvm.org/ce/z/c34qSU

    There was previously an implementation of this that work of Y was non-constant, but it was missing if Y*Z evaluated to a constant and/or nsw/nuw where both false. As well it only worked if Z was a constant but we can check 1s bit of KnownBits to cover more cases.
  1. (icmp eq/ne X*Z, Y*Z) [if Z != 0 and nsw(X*Y) and nsw(Y*Z)] -> (icmp eq/ne X, Y) EQ: https://alive2.llvm.org/ce/z/6SdAG6 NE: https://alive2.llvm.org/ce/z/fjsq_b

    This was previously implemented only to work if Z was constant, but we can use isKnownNonZero to cover more cases.
  1. (icmp uPred X*Y, Y*Z) [if Z != 0 and nuw(X*Y) and nuw(X*Y)] -> (icmp uPred X, Y) EQ: https://alive2.llvm.org/ce/z/FqWQLX NE: https://alive2.llvm.org/ce/z/2gHrd2 ULT: https://alive2.llvm.org/ce/z/MUAWgZ ULE: https://alive2.llvm.org/ce/z/szQQ2L UGT: https://alive2.llvm.org/ce/z/McVUdu UGE: https://alive2.llvm.org/ce/z/95uyC8

    This was previously implemented only for eq/ne cases. As well only if Z was constant, but again we can use isKnownNonZero to cover more cases.

Diff Detail

Event Timeline

goldstein.w.n created this revision.Jan 27 2023, 3:25 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 27 2023, 3:25 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
goldstein.w.n requested review of this revision.Jan 27 2023, 3:25 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 27 2023, 3:25 PM
goldstein.w.n added inline comments.Jan 27 2023, 3:48 PM
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
4432

Is there a better way to do this?

If the 3 improvements are independent, it would be better to make this into 3 small patches. That makes it easier to review and reduces risk.

If the 3 improvements are independent, it would be better to make this into 3 small patches. That makes it easier to review and reduces risk.

I"ll split case 1, but case 2/3 are basically in the same new code block.

Rebase + Split

If the 3 improvements are independent, it would be better to make this into 3 small patches. That makes it easier to review and reduces risk.

I split the constant case too D143026.

My preference is too keep the rest of this together, its three cases, but those three cases where what was covered in the previous
code block and I couldn't find a clean way to only partially insert this patch w.o causing regressions from missing cases b.c the old
code was removed.

spatel added inline comments.Feb 3 2023, 10:19 AM
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
4432

AFAIK, there's no direct way to specify/capture a common operand like that, but this way is shorter and easier to read since it doesn't need any extra operand names:

if (Pred == ICmpInst::getUnsignedPredicate(Pred) &&
    ((match(Op0, m_Mul(m_Value(X), m_Value(Z))) &&
      match(Op1, m_c_Mul(m_Specific(Z), m_Value(Y)))) ||
     (match(Op0, m_Mul(m_Value(Z), m_Value(X))) &&
      match(Op1, m_c_Mul(m_Specific(Z), m_Value(Y)))))) {
goldstein.w.n marked an inline comment as done.

Make X/Y/Z collection much better

spatel accepted this revision.Feb 6 2023, 4:37 AM

LGTM

This revision is now accepted and ready to land.Feb 6 2023, 4:37 AM