On Thu, Oct 15, 2026 at 02:04:44PM +0200, Richard Biener wrote: > A few kg CO2 later here's a prototype that looks like proper IPA > and LTO capable. Note it still does varpool handling early which > I think is OK. I'm not sure it fits a possible design of different > inline from non-inline bodies in more general (GNU extern inline). Thanks for this! I gave it a spin. It fixes both PR105438 testcases and a static-function case (the second patch adds it as gcc.dg/ipa/pr105438-5.c), but I ran into a few problems. These are solved by the two attached patches that apply on top of yours (on 84348add236): 1. Wrong code from IPA-CP. With the alias deferred, IPA-CP runs between the merge decision and the alias. For a local function it can't clone, it narrows the parameter ranges in place to what its own calls pass, so making the other function an alias of it sends it values outside them. 27 of the c-c++-common/torture/ builtin-arith-overflow tests abort at -O2 -flto, in C and C++, and this aborts at plain -O2: __attribute__ ((noinline, noclone)) static int f1 (int x, int y) { return x * 7 + y; } __attribute__ ((noinline, noclone)) static int f2 (int x, int y) { return x * 7 + y; } __attribute__ ((noinline)) int t1 (void) { return f1 (2, 3); } __attribute__ ((noinline)) int t2 (void) { return f2 (5, 1); } t2 returns 17. The first patch makes the alias, or redirects the alias's calls, only when the ranges IPA-CP gave the alias's parameters are within the original's. 2. Nodes in deferred_merge_aliases can be removed before the list is processed, by the IPA passes between ICF and the inliner. Building the kernel's fs/ext4/super.c crashed in can_remove_if_no_direct_calls_p on a removed node. The first patch adds a cgraph removal hook. 3. Your g++.dg/lto/pr105438_0.C passes without your patch: with -r the link is incremental and ICF never runs. The first patch adds -flinker-output=nolto-rel so it'll fail on master and pass with your patch. 4. It doesn't look like the optimization summary and the function transform are needed. Under LTO the inliner, and with it the alias creation, runs at WPA, so the aliases reach LTRANS the way ICF's aliases do now, and inline_transform already redirects the call statements. At LTRANS every streamed pair should already be an alias. Reading them also opened an ICF dump at LTRANS, which outputs.exp reports as an extra file (68 new FAILs). The first patch removes both hooks. 5. Only the alias path was deferred, so merges that took the wrapper/redirect path still inlined the other body: two global functions (both addresses matter), and everything on targets without symbol aliases. My original two-global-functions case still warned. The second patch handles that path with an inline-only copy: before the calls are redirected, the merged function's direct calls go to a copy of its own body, the wrapper is made as before, and after inlining the calls that weren't inlined go to the original and the copies go away. (I first tried just deferring the wrapper, but then the inliner never inlines the original into the wrapper, which changed code generation all over the testsuite and broke always_inline functions and interrupt handlers.) With both patches on yours, check-c and check-c++ on x86_64 match master. For the paths without symbol aliases I checked with an x86_64-apple-darwin cross compiler. An x86_64 allmodconfig kernel build gets the same ICF merge count as master and 7038 bytes more text (of 648 MB, so no big deal). The kernel case that started this, net/ipv6/ip6_tunnel.c, gets 16 warnings on m68k from GCC 16 but none from master, where r17-4004's check keeps the two functions apart because of their memcpy. The same code without the memcpy still gets the 16 warnings from master on m68k, and none with your patch, with or without mine on top. > > I'm sure this can be completed with some interaction, but our AI > > policy makes this questionable. These were written with an LLM's help too, especially the build orchestration and test creation. It has been explaining the glitches it found to me, and that's shaped the code, but I'm hardly a subject matter expert on aliases, inlining, and ICF. :P But if this direction looks right to you, we don't need my access path patch. -Kees -- Kees Cook