https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94693
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Or a bit more twisty struct A { int key; double payload_A; }; struct B { int key; int payload_B; }; void foo (int *key) { switch (*key) { case 1: ((struct A *)key)->payload_A = 1.0; break; case 2: ((struct B *)key)->payload_B = 1; break; default:; } } void bar() { struct A s; s.key = 1; foo (&s); } void baz() { struct B s; s.key = 2; foo (&s); } to show that the type of the variable to instantiate as storage in the callee is non-trivial (the only real constraint is it should be the maximum size of the storage actually accessed). Possibly simply make sure the actually passed types are types_compatible_p and use one of those. With the above cases it also appears that IPA CP could be the one handling this since &s is a (non-IP invariant) constant and the initializer is a constant as well. But I guess it's more IPA SRA.