[llvm-dev] Revisiting/refining the definition of optnone with interprocedural transformations

David Blaikie via llvm-dev llvm-dev at lists.llvm.org
Sun Apr 18 09:36:51 PDT 2021


While trying to reproduce some debug info thing (I don't have the exact
example at the moment - but I think it was more aggressive than the example
I have now, but something like this:

__attribute__((optnone)) int f1() {
  return 3;
}
int main() {
  return f1();
}


(actually I think in my case I had a variable to hold the return value from
f1, with the intent that this variable's location couldn't use a constant -
a load from a volatile variable would probably have provided similar
functionality in this case)

LLVM (& specifically Sparse Conditional Constant Propagation,
llvm/lib/Transforms/Scalar/SCCP.cpp) optimizes this code noting that f1
always returns 3, so rather than using the return value from the call to
f1, it ends up hardcoding the return value:

define dso_local i32 @main() local_unnamed_addr #1 {

entry:

  %call = tail call i32 @_Z2f1v()

  ret i32 3

}


I consider this a bug - in that optnone is used to implement -O0 for LTO,
so it seemed to me that the correct behavior is for an optnone function to
behave as though it were compiled in another object file outside the
purview of optimizations - interprocedural or intraprocedural.

So I sent https://reviews.llvm.org/D100353 to fix that.

Florian pointed out that this wasn't quite specified in the LangRef, which
says this about optnone:

This function attribute indicates that most optimization passes will skip
this function, with the exception of interprocedural optimization passes.
Code generation defaults to the “fast” instruction selector. This attribute
cannot be used together with the alwaysinline attribute; this attribute is
also incompatible with the minsize attribute and the optsize attribute.

This attribute requires the noinline attribute to be specified on the
function as well, so the function is never inlined into any caller. Only
functions with the alwaysinline attribute are valid candidates for inlining
into the body of this function.


So the spec of optnone is unclear (or arguably explicitly disallows)
whether interprocedural optimizations should treat optnone functions in any
particular way.

So I was going to update the wording to rephrase this to say
"Interprocedural optimizations should treat this function as though it were
defined in an isolated module/object." (perhaps "interprocedural
optimizations should treat optnone functions as opaque" or "as though they
were only declarations")

The choice of this direction was based on my (possibly incorrect or
debatable) understanding of optnone, that it was equivalent to the function
being in a separate/non-lto object. (this seems consistent with the way
optnone is used to implement -O0 under lto - you could imagine a user
debugging a binary, using -O0 for the code they're interested in debugging,
and potentially using an interactive debugger to change some state in the
function causing it to return a different value - which would get quite
confusing if the return value was effectively hardcoded into the caller)

What're folks thoughts on this?

- Dave
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210418/7e96e2dd/attachment.html>


More information about the llvm-dev mailing list