[llvm-dev] llvm.assume after CodeGenPrepare

Markus Lavin via llvm-dev llvm-dev at lists.llvm.org
Wed May 26 00:10:22 PDT 2021


Right, the canonicalization as described put in simplifycfg seems like a good thing to do longer term. For starters though it might be enough, at least for my use case, to simply stop dropping llvm.assume in codegenprepare unless the llvm.assume (and its predecessors) are the only instructions in a block. I think that would keep most people reasonably happy.

-Markus

> -----Original Message-----
> From: Johannes Doerfert <johannesdoerfert at gmail.com>
> Sent: den 25 maj 2021 17:14
> To: Jann Horn <jannh at google.com>; Markus Lavin
> <markus.lavin at ericsson.com>
> Cc: llvm-dev <llvm-dev at lists.llvm.org>
> Subject: Re: [llvm-dev] llvm.assume after CodeGenPrepare
> 
> 
> On 5/25/21 9:36 AM, Jann Horn via llvm-dev wrote:
> > On Tue, May 25, 2021 at 12:11 PM Markus Lavin
> <markus.lavin at ericsson.com> wrote:
> >> With recent changes in BasicAA (mostly by Nikita Popov I believe)
> llvm.assumes can now guide in the AA decision making. Which is of course
> great.
> >>
> >>
> >>
> >> For example for C input (or IR equivalent) as follows it can make a
> >> huge difference if the variable ‘x’ is known to be non-zero when AA
> >> is queried during scheduling
> >>
> >>
> >>
> >> __builtin_assume(x != 0);
> >>
> >> for (int i = 0; i < 64; i += 4) {
> >>
> >>    v[(i + 0) * x] = v[(i + 0) * x] >> 2;
> >>
> >>    v[(i + 1) * x] = v[(i + 1) * x] >> 2;
> >>
> >>    v[(i + 2) * x] = v[(i + 2) * x] >> 2;
> >>
> >>    v[(i + 3) * x] = v[(i + 3) * x] >> 2;
> >>
> >> }
> >>
> >>
> >>
> >> Unfortunately it appears that the CodeGenPrepare pass removes
> llvm.assume so that they never reach the code generator. Currently commit
> 91c9dee3fb6d89ab3 (and before that commit 6d20937c29a1a1d67) eliminate
> assumptions in CodeGenPrepare for reasons that appear to be optimization
> (avoiding blocks that would be empty if it was not for the llvm.assume and its
> predecessors).
> >>
> >>
> >>
> >> It seems these two efforts are quite contradictory. Is there any deeper
> thinking behind this? I for one would be in favor of not eliminating assumes.
> > Well, I'm fairly new to LLVM and don't really have much of a clue
> > about this. I just wanted to make a small improvement on top of the
> > existing work from 6d20937c29a1a1d67 without thinking all that much
> > about the overall design; and since codegenprepare was already
> > stripping it, I thought it would be safe to assume that no later pass
> > would use this information.
> >
> >
> > I was writing some code like this:
> >
> >      assert(ptr != nullptr || !ret); // no-op in release builds
> >      __builtin_assume(ptr != nullptr || !ret);
> >
> > Then I figured that it would look nicer and might (?) be nicer on the
> > optimizer to instead make it look like this:
> >
> >      if (ptr == nullptr) {
> >          assert(!ret); // no-op in release builds
> >          __builtin_assume(!ret);
> >      }
> >
> > but when I tried that, the result was that because the llvm.assume
> > only got stripped in a later part of the codegenprepare pass, the
> > branch condition was never eliminated (see
> > https://chromium-
> review.googlesource.com/c/chromium/src/+/2727400/2/base/memory/chec
> ked_ptr.h#120).
> > That seemed wrong to me; and since I saw that it was already stripped
> > later on in codegenprepare, I thought it'd be a good idea to do it a
> > bit earlier to allow removing the branch entirely.
> >
> >
> > I guess if you wanted to keep llvm.assume information around without
> > creating empty blocks, you'd have to instead let the codegenprepare
> > pass figure out whether blocks are empty except for llvm.assume and
> > its speculatable dependencies, and if so, either discard the whole
> > block or rewrite "if (COND1) __builtin_assume(COND2)" to something
> > like "__builtin_assume(!COND1 || COND2)"?
> 
> FWIW, I think the above is closer to what we want than 6d20937c29a1a1d67
> is.
> Deleting assumes should not happen deliberately if we don't have to.
> Instead,
> canonicalizations should be put in place, as described above. I'd do it before
> codegen though, simplifycfg, for example, could hoist assume from blocks
> that just contain it; in order to simplify the CFG ;) We could also add more of
> these into an assume specific pass, unsure what is best here.
> 
> ~ Johannes
> 
> 
> > _______________________________________________
> > LLVM Developers mailing list
> > llvm-dev at lists.llvm.org
> > https://protect2.fireeye.com/v1/url?k=9d78b188-c2e388e9-9d78f113-
> 86d8a
> > 30ca42b-e75f7c3dc456c928&q=1&e=8a48da16-7803-4175-a526-
> fef87bd423f4&u=
> > https%3A%2F%2Flists.llvm.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fllvm-
> dev


More information about the llvm-dev mailing list