On Wed, Jan 15, 2025 at 03:17:22PM +0100, Richard Biener wrote: > On Wed, 15 Jan 2025, Jakub Jelinek wrote: > > > On Wed, Jan 15, 2025 at 11:46:28AM +0100, Jakub Jelinek wrote: > > > BTW, I think we don't optimize returns-arg stuff like that at least right > > > now, and if we did, it wouldn't be through IPA-VRP, most of the > > > returns-arg > > > functions actually return a pointer, not integer and for prange we just > > > track constant values, not say address of something. > > > > I think for RA, perhaps we could add a REG_EQUIV note to the call insns > > which return singleton value range and let CSE etc. deal with that. > > So in case we expand from _1 = foo (); this looks sensible - add > a REG_EQUAL with the constant. But for the other way around I'm > not sure where to attach such note? Expand the LHS of the call > anyway and add it on the then unused set pseudo?
As can be seen on int foo (void); int bar (void) { foo (); return 1; } whenever a function doesn't return void, we expand it as (call_insn 5 2 6 2 (set (reg:SI 0 ax) (call (mem:QI (symbol_ref:DI ("foo") [flags 0x41] <function_decl 0x7fe47b788b00 foo>) [0 foo S1 A8]) (const_int 0 [0]))) "oui.c":5:3 -1 (expr_list:REG_CALL_DECL (symbol_ref:DI ("foo") [flags 0x41] <function_decl 0x7fe47b788b00 foo>) (nil)) (nil)) i.e. use the call_value form rather than call. So adding REG_EQUIV (or is that REG_EQUAL?, I'm always confused about that) on the CALL_INSN could just explain that ax has value say (const_int 42) or whatever else at that point. Whether CSE and/or LRA would make good use of that is to be seen when it is a hard register. Perhaps for CSE/combine it is undesirable to extend the lifetime of a hard register that way (unless we create a pseudo for it), but maybe LRA can handle it, dunno. Jakub