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.