https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119720
Bug ID: 119720
Summary: phiopt introduces out-of-bounds reads
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: kristerw at gcc dot gnu.org
Target Milestone: ---
phiopt2 miscompiles the following program when targeting x86_64 with the
options "-O3 -fno-strict-aliasing":
struct s {
int a;
int b;
};
int foo(int c, struct s *p)
{
int t;
if (c)
t = p->a;
else
t = p->b;
return t;
}
The GIMPLE before phiopt2 looks like this:
int foo (int c, struct s * p)
{
int t;
<bb 2> :
if (c_2(D) != 0)
goto <bb 3>;
else
goto <bb 4>;
<bb 3> :
t_6 = p_4(D)->a;
goto <bb 5>;
<bb 4> :
t_5 = p_4(D)->b;
<bb 5> :
# t_1 = PHI <t_6(3), t_5(4)>
return t_1;
}
This is valid for c == 1 when p points to a 4-byte buffer, even though the full
structure does not fit. But phiopt2 hoists both loads, causing t_5 to read out
of bounds:
int foo (int c, struct s * p)
{
int t;
<bb 2> :
t_6 = p_4(D)->a;
t_5 = p_4(D)->b;
if (c_2(D) != 0)
goto <bb 3>;
else
goto <bb 4>;
<bb 3> :
goto <bb 5>; [100.00%]
<bb 4> :
<bb 5> :
# t_1 = PHI <t_6(3), t_5(4)>
return t_1;
}