https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108445
Bug ID: 108445 Summary: Address expression on global variable is not normalized Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: fxue at os dot amperecomputing.com CC: marxin at gcc dot gnu.org Target Milestone: --- Created attachment 54296 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54296&action=edit testcase Compile two files with option "-flto -g -O2", --------addr_f1.c-------- int gArray[16]; --------addr_f2.c-------- extern int gArray[]; int foo(int *a) { int *p = a; return *p; } int main(int argc, char *argv[]) { if (argc & 1) gArray[argc - 1] = 1; if (argc > 1) return foo(gArray); return 0; } We will get an ICE as: addr_f2.c:10:5: error: invalid address operand in ‘mem_ref’ 10 | int main(int argc, char *argv[]) | ^ MEM[(int *)&gArray]; # VUSE <.MEM_9> _8 = MEM[(int *)&gArray]; during GIMPLE pass: fixup_cfg addr_f2.c:10:5: internal compiler error: verify_gimple failed 0xe87e8b verify_gimple_in_cfg(function*, bool, bool) ../../gcc/tree-cfg.cc:5647 0xd55eb4 execute_function_todo ../../gcc/passes.cc:2091 0xd567e3 do_per_function ../../gcc/passes.cc:1694 0xd567e3 execute_todo ../../gcc/passes.cc:2145 Detailed representation of above &gArray is &MEM_REF[&gArray], not a normalized address expression, which is rejected by gimple verifier. For an address expression on global variable, LTO gimple serializer would do a trick transformation to change it to such kind of redundant form, then rely on gimple de-serializer to revert the change. However, in some situation, de-serializer may fail to do that(as the testcase), this does not cause ICE because it almost happens on gimple-debug statement. With the commit "r13-4743-gda85bfc75024a92b97e60e4436863dd5789786ec", an constant address expression might be shared by gimple-debug and other statements , and thus makes the issue exposed. 1. # DEBUG BEGIN_STMT 2. # DEBUG a => &gArray 3. # DEBUG INLINE_ENTRY foo 4. # DEBUG BEGIN_STMT 5. # DEBUG p => &gArray 6. # DEBUG BEGIN_STMT 7. _10 = MEM[(int *)&gArray]; After early-inlining, the "main" function will end up with above gimples, in which stmt "5" and "7" refer to shared &gArray.