This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/55875] New: [4.8 Regression] IVopts caused miscompilation
- From: "jakub at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 04 Jan 2013 12:08:35 +0000
- Subject: [Bug tree-optimization/55875] New: [4.8 Regression] IVopts caused miscompilation
- Auto-submitted: auto-generated
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55875
Bug #: 55875
Summary: [4.8 Regression] IVopts caused miscompilation
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: jakub@gcc.gnu.org
The following testcase is miscompiled at -O3 on x86_64-linux starting with
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=192989
(ok, that revision doesn't compile, needs r192900 follow-up).
struct A
{
short int a1;
unsigned char a2;
unsigned int a3;
};
struct B
{
unsigned short b1;
const A *b2;
};
B b;
__attribute__((noinline, noclone))
int foo (unsigned x)
{
__asm volatile ("" : "+r" (x) : : "memory");
return x;
}
inline void
bar (const int &)
{
}
__attribute__((noinline)) void
baz ()
{
const A *a = b.b2;
unsigned int i;
unsigned short n = b.b1;
for (i = 0; i < n; ++i)
if (a[i].a1 == 11)
{
if (i > 0 && (a[i - 1].a2 & 1))
continue;
bar (foo (2));
return;
}
}
int
main ()
{
A a[4] = { { 10, 0, 0 }, { 11, 1, 0 }, { 11, 1, 0 }, { 11, 1, 0 } };
b.b1 = 4;
b.b2 = a;
baz ();
return 0;
}
In *.slp we have:
<bb 5>:
if (i_21 != 0)
goto <bb 6>;
else
goto <bb 7>;
<bb 6>:
_11 = i_21 + 4294967295;
_12 = (long unsigned int) _11;
_13 = _12 * 8;
_14 = a_4 + _13;
_15 = _14->a2;
but ivopts turns that into:
<bb 5>:
i_25 = (unsigned int) ivtmp.9_31;
if (i_25 != 0)
goto <bb 6>;
else
goto <bb 7>;
<bb 6>:
_28 = ivtmp.9_31 * 8;
_27 = a_4 + _28;
_26 = _27 + 34359738362;
_15 = MEM[base: _26, offset: 0B];
which is wrong, i_21 + -1U wrapped around (and wasn't executed for i_21 being
0), while 34359738362 is 0xffffffffULL * 8 + 2, thus it ignores the wrapping
and does what the original code would do for
_12 = (long unsigned int) i_21;
_77 = _12 + 4294967295;
_13 = _77 * 8;
i.e. as if the -1U addition was done in the wider precision.