[PATCH] D144610: [InstCombine] Add transforms for `(icmp upred (or X, Y), X)`
Noah Goldstein via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Sun May 28 09:12:11 PDT 2023
goldstein.w.n added inline comments.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:4127-4133
+ // icmp (X | noundef Y) eq/ne X
+ // if (X | noundef Y).hasOneUse()
+ // --> (X & noundef Y) eq/ne noundef Y
+ if (ICmpInst::isEquality(Pred) && Op0->hasOneUse() &&
+ isGuaranteedNotToBeUndefOrPoison(A, Q.AC, Q.CxtI, Q.DT,
+ /*Depth*/ 0))
+ return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, A), A);
----------------
goldstein.w.n wrote:
> nikic wrote:
> > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> >
> > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
> > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> >
> Agreed that is a limitation, but seems to me be better than nothing no?
>
> > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
>
> Although if Y is constant then it will be no undef so it will reach `X & Y == Y` -> `X & ~Y == 0` either way.
> > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> >
> Agreed that is a limitation, but seems to me be better than nothing no?
>
> > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
>
> Although if Y is constant then it will be no undef so it will reach `X & Y == Y` -> `X & ~Y == 0` either way.
================
Comment at: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp:4127-4133
+ // icmp (X | noundef Y) eq/ne X
+ // if (X | noundef Y).hasOneUse()
+ // --> (X & noundef Y) eq/ne noundef Y
+ if (ICmpInst::isEquality(Pred) && Op0->hasOneUse() &&
+ isGuaranteedNotToBeUndefOrPoison(A, Q.AC, Q.CxtI, Q.DT,
+ /*Depth*/ 0))
+ return new ICmpInst(Pred, IC.Builder.CreateAnd(Op1, A), A);
----------------
goldstein.w.n wrote:
> goldstein.w.n wrote:
> > nikic wrote:
> > > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> > >
> > > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
> > > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> > >
> > Agreed that is a limitation, but seems to me be better than nothing no?
> >
> > > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
> >
> > Although if Y is constant then it will be no undef so it will reach `X & Y == Y` -> `X & ~Y == 0` either way.
> > > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> > >
> > Agreed that is a limitation, but seems to me be better than nothing no?
> >
> > > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
> >
> > Although if Y is constant then it will be no undef so it will reach `X & Y == Y` -> `X & ~Y == 0` either way.
>
>
> > I'm somewhat skeptical about this fold. I can see where you're coming from here, in terms of picking a canonical form between and/or for this pattern, but the fact that we need the undef limitation here (so the canonicalization will be fairly unreliable) and that and/or are generally always handled in conjugate patterns (i.e. we shouldn't have cases where one optimizes better than the other) makes this fold not very compelling to me.
> >
> Agreed that is a limitation, but seems to me be better than nothing no?
>
> > The more obvious canonicalization choice would be `X & ~Y == 0`, but that adds an extra instruction. We do canonicalize this for the case where Y is a constant, but don't do it even if Y is freely invertable (https://llvm.godbolt.org/z/7MWefMbP9).
>
> Although if Y is constant then it will be no undef so it will reach `X & Y == Y` -> `X & ~Y == 0` either way.
I'm wrong about this. Okay ill update to make only for constants and do the ~Y version.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144610/new/
https://reviews.llvm.org/D144610
More information about the llvm-commits
mailing list