https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99670
Bug ID: 99670 Summary: IPA CP and SRA pass order issue? Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org CC: marxin at gcc dot gnu.org Target Milestone: --- struct X { int i; int j; }; int k; static void __attribute__((noinline)) bar (int *i) { k = *i; } static void __attribute__((noinline)) foo (struct X x) { bar (&x.j); } int main() { struct X x; x.i = 0; x.j = 1; foo (x); } this ends up being IPA optimized as ;; Function bar.isra (bar.isra.0, funcdef_no=3, decl_uid=1965, cgraph_uid=5, symbol_order=5) (executed once) __attribute__((noinline)) void bar.isra (int ISRA.3) { int * i; int * i; int _1; <bb 3> [local count: 1073741824]: <bb 2> [local count: 1073741824]: _1 = ISRA.3_2(D); k = _1; return; } ;; Function foo.constprop (foo.constprop.0, funcdef_no=4, decl_uid=1964, cgraph_uid=4, symbol_order=4) (executed once) __attribute__((noinline)) void foo.constprop (struct X x) { int _3; <bb 3> [local count: 1073741824]: <bb 2> [local count: 1073741824]: _3 = MEM[(int *)&x + 4B]; bar.isra (_3); return; } ;; Function main (main, funcdef_no=2, decl_uid=1952, cgraph_uid=3, symbol_order=3) (executed once) int main () { struct X x; <bb 2> [local count: 1073741824]: x.i = 0; x.j = 1; foo.constprop (x); x ={v} {CLOBBER}; return 0; } where the odd thing is that we have a foo.constprop clone that is not in any way modified (by IPA CP). IPA CP does figure that we pass two constant components but somehow even though IPA SRA turns the pass-by-referece into a pass by value the resulting constant propagation opportunity isn't realized. IPA CP has Jump functions: Jump functions of caller main/3: callsite main/3 -> foo/2 : param 0: UNKNOWN Aggregate passed by value: offset: 0, type: int, CONST: 0 offset: 32, type: int, CONST: 1 Unknown bits Unknown VR Jump functions of caller foo/2: callsite foo/2 -> bar/1 : param 0: UNKNOWN value: 0x0, mask: 0xfffffffffffffffc VR [1, -1] Jump functions of caller bar/1: Propagating constants: Initializing lattices of main/3 Marking all lattices as BOTTOM Initializing lattices of foo/2 Initializing lattices of bar/1 overall_size: 17 Setting dest_lattice to bottom, because type of param 0 of foo/2 is NULL or unsuitable for bits propagation but still does Estimating effects for foo/2. Estimating body: foo/2 Known to be false: size:5 time:13.000000 nonspec time:13.000000 loops with known iterations:0.000000 known strides:0.000000 - context independent values, size: 5, time_benefit: 0.000000 Decided to specialize for all known contexts, code not going to grow. ... IPA decision stage: Evaluating opportunities for foo/2. - Creating a specialized node of foo/2 for all known contexts. Accounting size:2.00, time:11.00 on predicate exec:(true) the new node is foo.constprop/4. Aggregate replacements: 0[0]=0, 0[32]=1 ... Modification phase of node foo.constprop/4 Aggregate replacements: 0[0]=0, 0[32]=1 __attribute__((noinline)) void foo.constprop (struct X x) { <bb 3> [local count: 1073741824]: <bb 2> [local count: 1073741824]: bar (&x.j); return; I wonder if IPA CP and IPA SRA should work more in concert (or be even unified).