[LLVMdev] Does nounwind have semantics?

Nick Lewycky nicholas at mxc.ca
Mon Jul 22 00:24:19 PDT 2013

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.


> Michael
> -----Original Message-----
> From: 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
> 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         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.

More information about the llvm-dev mailing list