Hal Finkel via llvm-dev
2017-Jul-14 01:18 UTC
[llvm-dev] failing to optimize boolean ops on cmps
On 07/13/2017 06:40 PM, Daniel Berlin via llvm-dev wrote:> Ah yes, it can only return one instruction and you need two. > > NewGVN could still handle it if instsimplify was changed to return the > right binary operators because it has infrastructure that can handle > insertion. > (it would need a little work). > > > (At this point, InstCombine seems to have become worse to me than > GCC's combining infrastructure, so i'd really like to see if we can > stop putting things there. Otherwise, we just go farther down the path > of 'let's just make everything one big graph rewrite)Perhaps something of a digression: My general impression is that if InstCombine were actually doing a principled graph rewrite, then we wouldn't have these problems. The problem we have, however, is that we have phase-ordering problems (even within the fixed-point iteration scheme): Patterns being matched depend on a canonical form, instructions nearly matching those patterns might be created, and then suboptimally consumed (i.e. further transformed), before being subject to the canonicalizing transformation(s) that would make the better pattern actually match. Except for TableGen'ing the whole thing, and making an actual graph automaton to match the patterns, it's not clear to me how to efficiently fix this. In the mean time, what we've been doing in practice, is that we have InstCombine patterns depend on canonical forms, until we hit some phase-ordering problem, and then we extend the pattern in question to match some non-canonical forms. We might do this here as well (if that's the problem here), but at some point I suspect we'll end up redoing everything. -Hal> > > On Thu, Jul 13, 2017 at 4:37 PM, Sanjay Patel <spatel at rotateright.com > <mailto:spatel at rotateright.com>> wrote: > > This can't be an instsimplify though? The values we want in these > cases do not exist already: > %res = or i8 %b, %a > %res = or i1 %cmp, %c > > > > On Thu, Jul 13, 2017 at 5:10 PM, Daniel Berlin > <dberlin at dberlin.org <mailto:dberlin at dberlin.org>> wrote: > > > > On Thu, Jul 13, 2017 at 2:12 PM, Sanjay Patel > <spatel at rotateright.com <mailto:spatel at rotateright.com>> wrote: > > We have several optimizations in InstCombine for bitwise > logic ops (and/or/xor) that fail to handle compare > patterns with the equivalent bitwise logic. Example: > > define i8 @or_and_not(i8 %a, i8 %b) { > %nota = xor i8 %a, -1 > %and = and i8 %nota, %b > %res = or i8 %and, %a > ret i8 %res > } > > define i1 @or_and_cmp_not(i32 %a, i32 %b, i1 %c) { > %cmp = icmp sgt i32 %a, %b > %cmp_inv = icmp sle i32 %a, %b ; this is 'not' of %cmp > %and = and i1 %c, %cmp_inv > %res = or i1 %cmp, %and > ret i1 %res > } > > $ ./opt -instcombine hidden_not.ll -S > > define i8 @or_and_not(i8 %a, i8 %b) { > %res = or i8 %b, %a > ret i8 %res > } > > define i1 @or_and_cmp_not(i32 %a, i32 %b, i1 %c) { > %cmp = icmp sgt i32 %a, %b > %cmp_inv = icmp sle i32 %a, %b > %and = and i1 %cmp_inv, %c > %res = or i1 %cmp, %and > ret i1 %res > } > > --------------------------------------------------------------------- > > Would adding to the existing InstCombine logic folds to > handle this kind of pattern be a welcome enhancement? I > don't know if it's possible to make the matchers handle > this case without adding a new matcher. Eg: > > > I would rather see this added to instsimplify than instcombine. > If you do that, GVN/et all will get this already. > > This probably does require a special matcher though: > > > We have: > if (m_c_And(m_Cmp(Pred, m_Value(), m_Value()), > m_Cmp(Pred, m_Value(), m_Value())) > > and you really want: > if (m_c_And(m_Cmp(Pred, m_Value(), m_Value()), > m_Cmp(m_Opposite(Pred), m_Value(), m_Value())) > > > > > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170713/1b8326df/attachment-0001.html>
Daniel Berlin via llvm-dev
2017-Jul-14 15:27 UTC
[llvm-dev] failing to optimize boolean ops on cmps
On Thu, Jul 13, 2017 at 6:18 PM, Hal Finkel <hfinkel at anl.gov> wrote:> > On 07/13/2017 06:40 PM, Daniel Berlin via llvm-dev wrote: > > Ah yes, it can only return one instruction and you need two. > > NewGVN could still handle it if instsimplify was changed to return the > right binary operators because it has infrastructure that can handle > insertion. > (it would need a little work). > > > (At this point, InstCombine seems to have become worse to me than GCC's > combining infrastructure, so i'd really like to see if we can stop putting > things there. Otherwise, we just go farther down the path of 'let's just > make everything one big graph rewrite) > > > Perhaps something of a digression: > > My general impression is that if InstCombine were actually doing a > principled graph rewrite, then we wouldn't have these problems. >Define "these problems"? :) I mean, you are right it would be better in general. But the notion of adding more and more graph rewrites to a single part of the compiler, to get second/third/etc order effects, is endless. Pretty much everything can be expressed as a set of graph rewrites. There is no principled stopping point. IE You have to decide what you want each pass to do, and if you have one pass whose job is "perform all possible graph rewrites", that pass is in fact, your compiler :) That's not such a bad thing, mind you, there are entire libraries/languages centered around this (see, e.g., stratego, https://en.wikipedia.org/wiki/Stratego/XT and http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/index.html), but it should be a deliberate thing.> e problem we have, however, is that we have phase-ordering problems (even > within the fixed-point iteration scheme): Patterns being matched depend on > a canonical form, instructions nearly matching those patterns might be > created, and then suboptimally consumed (i.e. further transformed), before > being subject to the canonicalizing transformation(s) that would make the > better pattern actually match. > > Except for TableGen'ing the whole thing, and making an actual graph > automaton to match the patterns, it's not clear to me how to efficiently > fix this >That is what people used to do, make parsing grammars, etc. Stratego is also quite efficient at term rewriting, from what i remember. . In the mean time, what we've been doing in practice, is that we have> InstCombine patterns depend on canonical forms, until we hit some > phase-ordering problem, and then we extend the pattern in question to match > some non-canonical forms. We might do this here as well (if that's the > problem here), but at some point I suspect we'll end up redoing everything. >The question i would have is "how do you know when you are done?". As I said, pretty much everything can be expressed as a graph transform, and the more it gets added here, the more people want to run instcombine 50 times because cse/gvn/you name it "doesn't do what they want". -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170714/54ebf781/attachment.html>
Hal Finkel via llvm-dev
2017-Jul-14 15:45 UTC
[llvm-dev] failing to optimize boolean ops on cmps
On 07/14/2017 10:27 AM, Daniel Berlin wrote:> > > On Thu, Jul 13, 2017 at 6:18 PM, Hal Finkel <hfinkel at anl.gov > <mailto:hfinkel at anl.gov>> wrote: > > > On 07/13/2017 06:40 PM, Daniel Berlin via llvm-dev wrote: >> Ah yes, it can only return one instruction and you need two. >> >> NewGVN could still handle it if instsimplify was changed to >> return the right binary operators because it has infrastructure >> that can handle insertion. >> (it would need a little work). >> >> >> (At this point, InstCombine seems to have become worse to me than >> GCC's combining infrastructure, so i'd really like to see if we >> can stop putting things there. Otherwise, we just go farther down >> the path of 'let's just make everything one big graph rewrite) > > Perhaps something of a digression: > > My general impression is that if InstCombine were actually doing a > principled graph rewrite, then we wouldn't have these problems. > > > Define "these problems"? > > :) > I mean, you are right it would be better in general. > But the notion of adding more and more graph rewrites to a single part > of the compiler, to get second/third/etc order effects, is endless. > Pretty much everything can be expressed as a set of graph rewrites. > There is no principled stopping point. IE You have to decide what you > want each pass to do, and if you have one pass whose job is "perform > all possible graph rewrites", that pass is in fact, your compiler :) > > That's not such a bad thing, mind you, there are entire > libraries/languages centered around this (see, e.g., stratego, > https://en.wikipedia.org/wiki/Stratego/XT and > http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/index.html), > but it should be a deliberate thing. > > e problem we have, however, is that we have phase-ordering > problems (even within the fixed-point iteration scheme): Patterns > being matched depend on a canonical form, instructions nearly > matching those patterns might be created, and then suboptimally > consumed (i.e. further transformed), before being subject to the > canonicalizing transformation(s) that would make the better > pattern actually match. > > Except for TableGen'ing the whole thing, and making an actual > graph automaton to match the patterns, it's not clear to me how to > efficiently fix this > > > That is what people used to do, make parsing grammars, etc. > Stratego is also quite efficient at term rewriting, from what i remember.AFAIK, that's true.> > . In the mean time, what we've been doing in practice, is that we > have InstCombine patterns depend on canonical forms, until we hit > some phase-ordering problem, and then we extend the pattern in > question to match some non-canonical forms. We might do this here > as well (if that's the problem here), but at some point I suspect > we'll end up redoing everything. > > > The question i would have is "how do you know when you are done?". As > I said, pretty much everything can be expressed as a graph transform, > and the more it gets added here, the more people want to run > instcombine 50 times because cse/gvn/you name it "doesn't do what they > want". >I think you're done when you get everything that you have that fits into a model of local transformations and that should be run to a fixed point. Certainly an interesting question, but I suspect that the practical answer is "what's in InstCombine." To do more in this sense probably requires some more-general scheme (e.g. equality saturation). -Hal -- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170714/39cede7d/attachment-0001.html>