[llvm-dev] help me understand how nounwind attribute on functions works?
Sanjoy Das via llvm-dev
llvm-dev at lists.llvm.org
Thu Feb 9 18:37:10 PST 2017
On Thu, Feb 9, 2017 at 6:25 PM, Mehdi Amini <mehdi.amini at apple.com> wrote:
>> On Feb 9, 2017, at 6:16 PM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:
>> On Thu, Feb 9, 2017 at 8:41 AM, Reid Kleckner via llvm-dev
>> <llvm-dev at lists.llvm.org> wrote:
>>> On Wed, Feb 8, 2017 at 5:45 PM, Mehdi Amini <mehdi.amini at apple.com> wrote:
>>>> What isn’t clear to me still is : why shouldn't this be transitive?
>>>> In the example you’re showing, for a caller of f() in bar, what is the
>>>> advantage of knowing that f() is nounwind if it an exception can still be
>>>> thrown? What does it allow?
>>> We know an exception cannot unwind out of f. An exception can be thrown
>>> inside something that f calls, but it must be caught before it unwinds
>>> beyond f.
>> So perhaps a viable rule is that every CallInst in a nounwind function
>> can be marked as nounwind (even though the callee for said CallInst
>> can't be)?
> That should be an implicit assumption when a given function has the attribute. A `isCallNounwind(CallSite &C)` should be allowed to be implemented conceptually: return C.getCaller()->hasNounwindAttr() || C.getCaller()->hasNounwindAttr();
> I’m still not sure what is LLVM doing differently for such calls thought? Why is it useful to know that a call is nounwind?
> I thought it is only useful to be able to turn invoke into calls, but what else?
Because nounwind functions do not have an implicit throw edge, you can
do things like:
int k = a / b;
int k = a / b;
Unfortunately the readnone (or readonly) is important in LLVM today;
since the informal semantics today are readnone or readonly functions
can't exit(0) or infloop.
More information about the llvm-dev