[LLVMdev] Does nounwind have semantics?

Eric Christopher
Thu, 25 Jul 2013 18:11:49 -0000

>> Regarding auditing the intrinsics – I’d prefer to do this in stages.
>
>
> Sounds fine. I'd like Eric to take a quick look and agree that marking
debug
> intrinsics speculatable is sane. (Yes they already are, but that
doesn't
> mean it's sane. I also want Eric to know that 'speculatable' is
going to
> start showing up in his debug info.)
>

Sure, seems reasonable so far.

-eric

> One other thing, your patch and Tobias Grosser's patch (subject
"Make .bc
> en/decoding of AttrKind stable") are in conflict. Whoever lands second
will
> need to merge.
>
> Nick
>
>> Here I’m just preserving the current behavior by marking intrinsics
that
>> used to be explicitly handled in isSafeToSpeculativelyExecute(), so
>> there should be no functional change.
>>
>> *From:*Nick Lewycky [mailto:nlewycky at google.com]
>> *Sent:* Tuesday, July 23, 2013 02:29
>> *To:* Kuperstein, Michael M
>> *Cc:* Nick Lewycky; llvmdev at cs.uiuc.edu
>> *Subject:* Re: [LLVMdev] Does nounwind have semantics?
>>
>>
>> On 22 July 2013 01:11, Kuperstein, Michael M
>> <michael.m.kuperstein at intel.com <mailto:michael.m.kuperstein
at intel.com>>
>>
>> wrote:
>>
>>     Of course frontends are free to put attributes, but it would be
nice
>>     if optimizations actually used them. ;-)
>>     My use case is that of proprietary frontend that happens to know
>>     some library function calls - which are only resolved at link time
-
>>     have no side effects and are safe to execute speculatively, and
>>     wants to tell the optimizer it can move them around however it
>>     likes. I'll gladly submit a patch that uses these hints, but
I'd
>>     like to reach some consensus on what the desired attributes
actually
>>     are first. The last thing I want is to add attributes that are only
>>     useful to myself.
>>
>>     Regarding having several orthogonal attributes vs. things like
>>     "safetospeculate":
>>
>>     To know a function is safe to speculatively execute, I need at
least:
>>     1) readnone (readonly is insufficient, unless I know all accessed
>>     pointers are valid)
>>     2) nounwind
>>     3) nolongjmp (I guess?)
>>     4) no undefined behavior. This includes things like
"halting" and
>>     "no division by zero", but that's not, by far, an
exhaustive list.
>>
>>     I guess there are several ways to handle (4).
>>     Ideally, I agree with you, we'd like a set of orthogonal
attributes
>>     that, taken together, imply that the function's behavior is not
>>     undefined.
>>     But that requires mapping all sources of undefined behavior (I
don't
>>     think this is currently documented for LLVM IR, at least not in a
>>     centralized fashion) and adding a very specific attribute for each
>>     of them. I'm not sure having function declarations with
"readnone,
>>     nounwind, nolongjmp, halting, nodivbyzero, nopoisonval,
>>     nocomparelabels, nounreachable, ..." is desirable.
>>
>>     We could also have a "welldefined" attribute and a
"halting"
>>     attribute where "welldefined" subsumes
"halting", if the specific
>>     case of a function which halts but may have undefined behavior is
>>     important.
>>     While the two are not orthogonal, it's similar to the situation
with
>>     "readnone" and "readonly". Does that sound
reasonable?
>>
>> You're entirely right. I forgot about undefined behaviour.
>>
>> If you want a 'speculatable' attribute, I would review that
patch.
>> Please audit the intrinsics (at least the target-independent ones) and
>> appropriate library functions for whether you can apply this attribute
>> to them. I think the only optimization that it can trigger is that
>> "isSafeToSpeculativelyExecute" returns true on it. Anything
else? Is it
>> safe to infer readnone and nounwind from speculatable?
>>
>> I should mention that speculatable functions are extraordinarily
limited
>> in what they can do in the general (non–LLVM-as-a-library) case. They
>> may be hoisted above calls to fork or pthread_create, they may be moved
>> into global constructors (and thus can't depend on global state),
etc.
>> However, since you have a specific library you want to generate code
>> against, you have the power to make use of it. I don't expect clang
or
>> dragonegg to be able to make use of it.
>>
>> Nick
>>
>>     -----Original Message-----
>>     From: Nick Lewycky [mailto:nicholas at mxc.ca <mailto:nicholas
at mxc.ca>]
>>     Sent: Monday, July 22, 2013 10:24
>>     To: Kuperstein, Michael M
>>     Cc: Andrew Trick; llvmdev at cs.uiuc.edu <mailto:llvmdev at
cs.uiuc.edu>
>>     Subject: Re: [LLVMdev] Does nounwind have semantics?
>>
>>     Kuperstein, Michael M wrote:
>>      > I'm not sure I understand why it's blocked on that,
by the way.
>>
>>     It blocks our ability to automatically deduce the halting attribute
>>     in the optimizer, which was necessary for the use case I had at the
>>     time.
>>     If you have a use case of your own, feel free to propose the patch!
>>
>>     (Technically it's not *blocked* -- see how my patch does it! --
but
>>     the workarounds are too horrible to be committed.)
>>
>>      > Even if we can't apply the attribute ourselves, I
don't see why
>>     we wouldn't expose that ability to frontends.
>>
>>     Frontends are free to put attributes on functions if they want to.
>>     Go for it!
>>
>>      > I'm not entirely sure "halting" is the right
attribute either, by
>>     the way.
>>      > What I, personally, would like to see is a way to specify a
>>     function call is safe to speculatively execute. That implies
>>     readnone (not just readonly), nounwind, halting - and Eris knows
>>     what else. Nick, is that too strong for you?
>>
>>     I strongly prefer the approach of having orthogonal attributes.
>>     There are optimizations that you can do with each of these
>>     attributes on their own. In particular I think that
>>     readonly+halting+nounwind+nolongjmp is going to be common and
I'd
>>     feel silly if we had a special case for
>>     readnone+halting+nounwind+nolongjmp and thus couldn't optimize
the
>> more
>>     common case.
>>
>>     That said, I'm also going to feel silly if we don't end up
with enough
>>     attributes to allow isSafeToSpeculate to deduce it, which is where
we
>>     are right now. I was planning to get back to fixing this after
>>     Chandler's promised PassManager work.
>>
>>     Nick
>>
>>      >
>>      > Michael
>>      >
>>      > -----Original Message-----
>>      > From: llvmdev-bounces at cs.uiuc.edu
>>     <mailto:llvmdev-bounces at cs.uiuc.edu>
>>     [mailto:llvmdev-bounces at cs.uiuc.edu
>>     <mailto:llvmdev-bounces at cs.uiuc.edu>] On Behalf Of Nick
Lewycky
>>      > Sent: Monday, July 22, 2013 07:08
>>      > To: Andrew Trick
>>      > Cc: llvmdev at cs.uiuc.edu <mailto:llvmdev at
cs.uiuc.edu>
>>      > Subject: Re: [LLVMdev] Does nounwind have semantics?
>>      >
>>      > Andrew Trick wrote:
>>      >> Does 'nounwind' have semantics that inform
optimization passes?
>>     It seems to in some cases, but not consistently. For example...
>>      >>
>>      >> int32_t foo(int32_t* ptr) {
>>      >> int i = 0;
>>      >> int result;
>>      >> do {
>>      >> bar(ptr);
>>      >> result = *ptr;
>>      >> bar(ptr);
>>      >> } while (i++< *ptr);
>>      >> return result;
>>      >> }
>>      >>
>>      >> Say we have a front end that declares bar as...
>>      >>
>>      >> declare void @bar(i32*) readonly;
>>      >>
>>      >> So 'bar' is 'readonly' and
'may-unwind'.
>>      >>
>>      >> When LICM tries to hoist the load it interprets the
'may-unwind'
>>     as "MayThrow" in LICM-language and bails. However, when
it tries to
>>     sink the call itself it sees the 'readonly', assumes no
side effects
>>     and sinks it below the loads. Hmm...
>>      >>
>>      >> There doesn't appear to be a way to declare a
function that is
>>     guaranteed not to write to memory in a way that affects the caller,
>>     but may have another well-defined side effect like aborting the
>>     program. This is interesting, because that is the way runtime
checks
>>     for safe languages would like to be defined. I'm perfectly
happy
>>     telling front ends to generate control flow for well-defined traps,
>>     since I like lots of basic blocks in my IR. But I'm still
curious
>>     how others deal with this.
>>      >
>>      > Yes, we went through a phase where people would try to use
>>     "nounwind+readonly == no side-effects" to optimize. All
such
>>     optimizations are wrong. Unless otherwise proven, a function may
>>     inf-loop, terminate the program, or longjmp.
>>      >
>>      > I tried to add 'halting' to help solve part of this a
long time
>>     ago, but it never went in. The problem is that determining whether
>>     you have loops requires a FunctionPass (LoopInfo to find loops and
>>     SCEV to determine an upper bound) and applying function attributes
>>     is an SCC operation (indeed, an SCC is itself a loop), so it's
all
>>     blocked behind fixing the PassManager to allow CGSGGPasses to
depend
>>     on FunctionPasses.
>>      >
>>
>>
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20100705/103670.html
>>      >
>>      > I'm now in a similar situation where I want
'nounwind' to mean
>>     "only exits by terminating the program or a return
instruction" but
>>     unfortunately functions which longjmp are considered nounwind. I
>>     would like to change llvm to make longjmp'ing a form of
unwinding
>>     (an exceptional exit to the function), but if I were to apply that
>>     rule today then we'd start putting dwarf eh tables on all our C
>>     code, oops.
>>      >
>>      > Nick
>>      > _______________________________________________
>>      > LLVM Developers mailing list
>>      > LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>>
>>     http://llvm.cs.uiuc.edu
>>      > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>      >
>> ---------------------------------------------------------------------
>>      > Intel Israel (74) Limited
>>      >
>>      > This e-mail and any attachments may contain confidential
material
>> for
>>      > the sole use of the intended recipient(s). Any review or
>> distribution
>>      > by others is strictly prohibited. If you are not the intended
>>      > recipient, please contact the sender and delete all copies.
>>      >
>>      >
>>
>>
---------------------------------------------------------------------
>>     Intel Israel (74) Limited
>>
>>     This e-mail and any attachments may contain confidential material
for
>>     the sole use of the intended recipient(s). Any review or
distribution
>>     by others is strictly prohibited. If you are not the intended
>>     recipient, please contact the sender and delete all copies.
>>
>>
>>     _______________________________________________
>>     LLVM Developers mailing list
>>     LLVMdev at cs.uiuc.edu <mailto:LLVMdev at cs.uiuc.edu>
>> http://llvm.cs.uiuc.edu
>>
>>     http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>> ---------------------------------------------------------------------
>> Intel Israel (74) Limited
>>
>> This e-mail and any attachments may contain confidential material for
>> the sole use of the intended recipient(s). Any review or distribution
>> by others is strictly prohibited. If you are not the intended
>> recipient, please contact the sender and delete all copies.
>>
>