[PATCH] D154306: [InstCombine] Generalise ((x1 ^ y1) | (x2 ^ y2)) == 0 transform to more than two pairs of variables
Maksim Kita via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 7 03:31:57 PDT 2023
kitaisreal added inline comments.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:2041
+ SmallVector<std::pair<Value *, Value *>, 2> CmpValues;
+ SmallVector<llvm::Value *, 16> WorkList(1, Or);
+
----------------
nikic wrote:
> Unnecessary `llvm::` prefix here and elsewhere.
Updated.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:2052
+ Value *OrLhs = OrOperator->getOperand(0),
+ *OrRhs = OrOperator->getOperand(1);
+
----------------
nikic wrote:
> goldstein.w.n wrote:
> > Prefer not name these `Or*` as you expect to match them for `Xor`. Can you just make these `Lhs`/`Rhs`.
> These are the Lhs/Rhs of an Or though. Lhs/Rhs of the Xor are matched below.
>
> Not sure why this isn't doing `match(CurrentValue, m_Or(m_Value(OrLhs), m_Value(OrRhs))` though.
Updated implementation to use `match`.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:2061
+
+ if (match(OrRhs, m_OneUse(m_Xor(m_Value(Lhs), m_Value(Rhs))))) {
+ CmpValues.emplace_back(Lhs, Rhs);
----------------
goldstein.w.n wrote:
> The `match(Op, Xor) { emplace(XorOps) } else { WorkList.Add(Op) }` could be a lambda for LHS/RHS.
Updated.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:2068
+
+ if (Match) {
auto BOpc = Pred == CmpInst::ICMP_EQ ? Instruction::And : Instruction::Or;
----------------
goldstein.w.n wrote:
> At first I thought this should be `!CmpValues.empty()` so you can match something like:
>
> `(or (or (xor A, B), (xor C, D)), (and E, F))` but realize we will visit the inner or and handle it there. Can you add a comment here (or above where you set `Match` to false) that such a case will inherently be handled so its okay to fail on any non-or/xor.
It seems that more easier approach is to clear `CmpValues` if we fail to match.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:2080
+ CmpValues.begin()->second);
+ return BinaryOperator::Create(BOpc, LhsCmp, RhsCmp);
}
----------------
nikic wrote:
> Why does this one need to be handled separately?
To properly support lifetime of allocated operators we must allocate them using `Builder`, and `Builder` methods return `Value *`.
But this function expects to return `BinaryOperator *` instead of `Value *`, so last one handled separately.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:2038
+ // ((X1 ^ X2) || (X3 ^ X4) || (X5 ^ X6)) == 0 --> (X1 == X2) && (X3 == X4) && (X5 == X6)
+ // ((X1 ^ X2) || (X3 ^ X4) || (X5 ^ X6)) != 0 --> (X1 != X2) || (X3 != X4) || (X5 != X6)
+ bool Match = false;
----------------
goldstein.w.n wrote:
> kitaisreal wrote:
> > goldstein.w.n wrote:
> > > Maybe add as a todo, but this also works for `sub` (or implement in a follow up patch!)
> > I can implement this in follow up patch.
> Thanks :)
> Can you add `TODO` for it in the meantime.
Added TODO.
================
Comment at: llvm/test/Transforms/InstCombine/icmp-or.ll:415
+ ret i1 %cmp
+}
----------------
goldstein.w.n wrote:
> goldstein.w.n wrote:
> > Can you 1) split the tests to a seperate patch (so we can see the diff this patch generates).
> > 2) Can you add a few negative tests (maybe where cmp is not against 0, one of the xors has multiuse, where its or->or (invalid), etc...).
> This is still outstanding.
I moved tests into separate patch https://reviews.llvm.org/D154384. Should we merge it first so we can see the difference after this patch is applied ?
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D154306/new/
https://reviews.llvm.org/D154306
More information about the llvm-commits
mailing list