[Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109112 --- Comment #8 from Jakub Jelinek --- (In reply to Jason Merrill from comment #7) > Why don't the existing optimizations work on the artificial function the > same as any other function? i.e. like > > struct S { bool x; }; > void do_something(); > inline void assumption_1 (const S& s) noexcept { > if (s.x) __builtin_unreachable (); > } > void fn(S s) { > assumption_1 (s); > if (s.x) do_something(); > } > > which is also optimized as expected. Because the assumptions have different representation in the IL. While normal calls look like: ret = foo (arg1, arg2, arg3); and we can inline those etc., because the assumptions potentially contain side-effects which shouldn't be evaluated and therefore should e.g. not be inlined nor assumed that they are actually called, the representation is like: .ASSUME (, arg1, arg2, arg3); where foo is that artificial assumption function which takes arg1, arg2, arg3. The above behaves like if (!foo (arg1, arg2, arg3)) __builtin_unreachable (); except that the function actually isn't called (nor emitted into assembly etc.). The assumption is if this function would be called and returned false at this spot, it would be UB. So, VRP walks the assumption function (after optimizations are performed on it, e.g. inlining into those and various other optimizations) backwards from the return value starting with [1, 1] and from that derives ranges for the arguments. Similarly to how for functions which aren't inlined but can be e.g. cloned it is essential to get IPA SRA and IPA CP etc. optimizations to tweak the arguments of functions (scalarize them, remove unneeded ones, replace others), it is needed that we optimize the assumptions similarly. The assumption functions should be always static and often will have a single reference (unless inlined multiple times / loop unrolled), so it is just fine to tweak them, just those optimizations will need to special case the IFN_ASSUME internal calls and treat .ASSUME (, arg1, arg2, arg3); more like foo (arg1, arg2, arg3); (i.e. off by one argument and treat it as if there was a call edge from the .ASSUME caller to foo.
[Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109112 --- Comment #7 from Jason Merrill --- In an email thread Jakub wrote: Only the simplest assumptions in [[assume(cond)]] where there clearly aren't any side-effects no risks of them are lowered to if (!cond) __builtin_unreachable (); in the IL, anything else goes into the condition being outlined in a separate artificial function and an internal function recording the assumption in the IL. The optimizers then can optimize both the artificial function and the caller. The missed optimization thing is that currently only the value range propagation is able to take advantage of the assumptions, and VRP is only able to deal with scalars. We have interprocedural optimizations like IPA scalar replacement of aggregates etc., where we can optimize passing aggregates at function boundaries to passing just some scalars from them if the rest isn't needed etc., but because the assumptions aren't normal calls they'd need tweaks to be able to optimize the assumptions too so that VRP could take advantage of those. Why don't the existing optimizations work on the artificial function the same as any other function? i.e. like struct S { bool x; }; void do_something(); inline void assumption_1 (const S& s) noexcept { if (s.x) __builtin_unreachable (); } void fn(S s) { assumption_1 (s); if (s.x) do_something(); } which is also optimized as expected.
[Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109112 Jakub Jelinek changed: What|Removed |Added CC||jamborm at gcc dot gnu.org --- Comment #6 from Jakub Jelinek --- CCing Martin, I don't have sufficient experience with IPA SRA nor IPA CP to be able to handle this.
[Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109112 Jason Merrill changed: What|Removed |Added CC||jason at gcc dot gnu.org Last reconfirmed||2023-07-13 Status|UNCONFIRMED |NEW Ever confirmed|0 |1 --- Comment #5 from Jason Merrill --- Note that the __builtin_unreachable variant is optimized as expected: struct S { bool x; }; void do_something(); void fn(S s) { if (s.x) __builtin_unreachable (); if (s.x) do_something(); } It's unfortunate that [[assume (x)]] is currently so much less useful than if (!x) __builtin_unreachable(), which expresses almost the same thing.
[Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109112 --- Comment #4 from Jakub Jelinek --- One way to improve this case would be to teach IPA SRA/CP etc. to perform some optimizations on the .ASSUME ifn calls and their corresponding functions, in this case if SRA would turn the argument from aggregate to scalar.
[Bug tree-optimization/109112] [[assume(...)]] is not taken into account for structs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109112 --- Comment #3 from Andrew Pinski --- I also suspect this is a dup of bug 109045 really.