Open Quuxplusone opened 8 years ago
Attached main.c
(187 bytes, text/x-c): code
Yeah, I think this is interprocedural constant propagation, plus attribute detection (detecting that the function is pure & thus an unused call can be omitted).
I /think/ there's another attribute for documenting that the optimizer shouldn't do anything interprocedural with the function, but I don't recall what it is.
(In reply to comment #1)
> Yeah, I think this is interprocedural constant propagation, plus attribute
> detection (detecting that the function is pure & thus an unused call can be
> omitted).
Thanks - indeed, if I make the Test function more involved (e.g., have it
return the result of another printf call), then things start to work more as
I'd expect.
More gcc explorer links:
No attributes - call inlined: http://goo.gl/Usoi0q
__attribute__((noinline)) - call not inlined: http://goo.gl/dAiUoY
> I /think/ there's another attribute for documenting that the optimizer
> shouldn't do anything interprocedural with the function, but I don't recall
> what it is.
That gave me a keyword to look for in
http://clang.llvm.org/docs/AttributeReference.html, but nothing obvious turned
up.
Regards,
--Tom
I was about to file another instance of this and was pointed here by the
duplicate detector. This still happens with trunk r336407.
(In reply to David Blaikie from comment #1)
> I /think/ there's another attribute for documenting that the optimizer
> shouldn't do anything interprocedural with the function, but I don't recall
> what it is.
Adding __attribute__((optnone)) forces the call to be generated in our case,
but that's a pretty big hammer. Do you have any better suggestions for a
workaround, or any expected timeframe for a fix? Thanks!
hey Chandler - I know we talked a while back about some bugs related to optnone that I think I fixed (yeah, bunch of GlobalsModRef and FunctionAttrs+OptNone situations). Any idea what, if anything, should be done in this noinline situation? This does sort of look like inlining, even if it isn't done by the inliner... (admittedly GCC has the same caveat, but a clearer workaround - I haven't checked why an asm("") is insufficient to hinder Clang here)
I stumbled on the same problem a few days ago.
I tracked the problem down to inter-procedural constant propagation, as
mentioned in the previous posts.
There is a simple fix to do for this: The "naked" attribute is already checked
to prevent inter-procedural constant propagation, I propose to add also a check
on the "noinline" attribute.
I will submit a patch under Phabricator.
I believe optnone
is the best tool we have to shut down all interprocedural optimizations.
Adding something that only targets interprocedural cases would be challenging. It's possible we could do this, but it would need very clear and strong motivation. It would add a lot of complexity to reasoning about IR semantics in an area that is already really complex (derefinement, etc, etc).
(In reply to Chandler Carruth from comment #6)
I believe
optnone
is the best tool we have to shut down all interprocedural optimizations.Adding something that only targets interprocedural cases would be challenging. It's possible we could do this, but it would need very clear and strong motivation. It would add a lot of complexity to reasoning about IR semantics in an area that is already really complex (derefinement, etc, etc).
But "optnone" does not prevent interprocedural constant propagation when LTO is used. Maybe "optnone" should also disable this optimization in LTO mode ?
(In reply to francois.de-ferriere from comment #7)
(In reply to Chandler Carruth from comment #6)
I believe
optnone
is the best tool we have to shut down all interprocedural optimizations.Adding something that only targets interprocedural cases would be challenging. It's possible we could do this, but it would need very clear and strong motivation. It would add a lot of complexity to reasoning about IR semantics in an area that is already really complex (derefinement, etc, etc).
But "optnone" does not prevent interprocedural constant propagation when LTO is used. Maybe "optnone" should also disable this optimization in LTO mode ?
Could you provide an example of that? I believe optnone /should/ prevent that - /that/ is probably a bug if it doesn't.
(In reply to David Blaikie from comment #8)
(In reply to francois.de-ferriere from comment #7)
(In reply to Chandler Carruth from comment #6)
I believe
optnone
is the best tool we have to shut down all interprocedural optimizations.Adding something that only targets interprocedural cases would be challenging. It's possible we could do this, but it would need very clear and strong motivation. It would add a lot of complexity to reasoning about IR semantics in an area that is already really complex (derefinement, etc, etc).
But "optnone" does not prevent interprocedural constant propagation when LTO is used. Maybe "optnone" should also disable this optimization in LTO mode ?
Could you provide an example of that? I believe optnone /should/ prevent that - /that/ is probably a bug if it doesn't.
Here is a very simple example. On this example, with or without -flto, the constant value in the callee is 'inlined'into the caller, although the caller still performs the call to the callee.
int attribute((noinline, optnone)) v1() { return 0xab; } int main() { return v1(); }
main.c
(187 bytes, text/x-c)