[PATCH] D83906: [CodeGen] Emit a call instruction instead of an invoke if the called llvm function is marked nounwind

John McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 9 13:27:49 PST 2023


rjmccall added a comment.

In D83906#4182287 <https://reviews.llvm.org/D83906#4182287>, @dexonsmith wrote:

> - At IRGen time, you know the LLVM attributes have not been adjusted after the optimized refined the function's behaviour. It should be safe to have IPA peepholes, as long as IRGen's other peepholes don't refine behaviour and add attributes based on that.
> - In the optimizer, if you're looking at de-refineable function then you don't know which attributes come directly from the source and which were implied by optimizer refinements. You can't trust you'll get the same function attributes at runtime.

Hmm.  I see what you're saying, but it's an interesting question how it applies here.  In principle, the optimizer should not be changing the observable semantics of functions, which certainly includes things like whether the function throws.  Maybe the optimizer can only figure out that a function throws in one TU, but if it "figures that out" and then a function with supposedly the same semantics actually does throw — not just retains the static ability to throw on a path that happens not to be taken dynamically, but actually throws at runtime — then arguably something has gone badly wrong.  As I recall, the de-refinement discussion was originally about properties that are *not* invariant to optimization in this way, things like whether the function uses one of its arguments.  Those properties are not generally considered to be part of the function's externally-observable semantics.

Of course, that's making a lot of assumptions about both what transformations are legal and to what extent they can be observed.  All bets are off the second you have a single transformation that's observable in code.  For example, we have a C++ optimization that promotes scoped heap allocations to the stack; that can definitely change whether exceptions are thrown, and then you can handle that exception and change return values, trigger extra side effects, and so on.  I don't think anyone wants to argue that we shouldn't do that optimization.  Even more simply, fast-math optimization can certainly change return values; and of course *anything* can change semantics under SEH.

Even if we just need to assume that that's always going to be possible in LLVM — that there will always be optimizations in play that can arbitrarily change observable semantics — maybe we can at least be a little more principled about them?  It's still true that the vast majority of transformations in LLVM cannot trigger arbitrary changes to source semantics, at least when SEH isn't in use.  Most transformations that change semantics are pretty narrow in practice — they don't touch most functions — so instead of conservatively assuming that *any* function might have been altered, it's probably profitable to track that on specific functions.  That would at least eliminate this artificial boundary between the frontend and the optimizer: the optimizer would have the information it would need to do this analysis on unaltered functions.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83906/new/

https://reviews.llvm.org/D83906



More information about the cfe-commits mailing list