On Thu, Mar 05, 2026 at 01:55:52PM +0100, Josef Melcr wrote:
> this patch enables IPA-SRA for internal .ASSUME calls. Consider the
> following testcase:
>
> struct S
> {
> bool x;
> };
>
> void
> foo(struct S s)
> {
> [[assume (!s.x)]];
> if (s.x)
> __builtin_abort ();
> }
>
> The [[assume (...)]] statement gets lowered to (simplified):
>
> bool foo.assume_fn(struct S s)
> {
> return !s.x;
> }
>
> void
> foo(struct S s)
> {
> .ASSUME (foo.assume_fn, s);
> if (s.x)
> __builtin_abort ();
> }
>
> The internal call to .ASSUME represents an indirect call to
> foo.assume_fn. Later on, the assume function is walked back from the
> return statement and vrp tries to figure out value ranges to make the
> function return true. However, as it encouters the struct, it assigns
> it a varying range and gives up, making the assumption pointless.
>
> This patch allows GCC to split the struct, remove pointers and so on
> through SRA, making the value range propagation more useful. It does so
> through adding callback edges to appropriately describe the indirect
> call to the assume body function and allowing GCC to modify the call
> statement.
Thanks for working on this. I'll defer the IPA review to Martin/Honza,
my knowledge of the IPA passes is limited, I'll just note that this is
highly desirable (maybe not just IPA-SRA for it but other IPA optimizations,
perhaps IPA-CP, IPA-VRP etc.) and just want to note that due to inlining
and unrolling and other code copying one can end up with multiple
.ASSUME ifn calls for the same *.assume_fn, and if that happens one needs
to be careful (similarly to other IPA optimizations with static function
and multiple callers in the TU) to optimize it with all callers (in this
case "callers") in mind and adjust them all, rather than just assuming
there must be exactly one. But if all corresponding .ASSUME calls for
a particular *.assume_fn can be changed, changing arguments the normal
IPA way is fine and desirable, except normal calls look like
foo (arg1, arg2, arg3) but in this case it is
.ASSUME (&foo.assume_fn, arg1, arg2, arg3).
Jakub