On 5/20/2015 3:27 AM, Richard Biener wrote:
On Mon, May 18, 2015 at 10:01 PM, mark maule <mark.ma...@oracle.com> wrote:
I have a loop which hangs when compiled with -O2, but runs fine when
compiled with -O1. Not sure what information is required to get an answer,
so starting with the full src code. I have not attempted to reduce to a
simpler test case yet.
Attachments:
bs_destage.c - full source code
bs_destage.dis.O2 - gdb disassembly of bs_destageLoop()
bs_destage.dis+m.O2 - src annotated version of the above
The function in question is bs_destageSearch(). When I compile bs_destage.c
with -O2, it seems that the dgHandle condition at line 741 is being ignored,
leading to an infinite loop. I can see in the disassembly that dgHandle is
still in the code as a 16-bit value stored at 0x32(%rsp), and a running
32-bit copy stored at 0x1c(%rsp). I can also see that the 16 bit version at
0x32(%rsp) is being incremented at the end of the loop, but I don't see
anywhere in the code where either version of dgHandle is being used when
determining if the while() at 741 should be continued.
I'm not very familiar with the optimizations that are done in O2 vs O1, or
even what happens in these optimizations.
So, I'm wondering if this is a bug, or a subtle valid optimization that I
don't understand. Any help would be appreciated.
Note: changing the declaration of dgHandle to be volitile appears to modify
the code sufficiently that it looks like the dgHandle check is honored (have
not tested).
Thanks in advance for any help/advice.
The usual issue with this kind of behavior is out-of-bound accesses of
arrays in a loop
or invoking undefined behavior when signed integer operations wrap.
uint32_t outLun[ BS_CFG_DRIVE_GROUPS ];
and
while ( ( dgHandle < ( BS_CFG_DRIVE_GROUPS + 1 ) ) &&
...
dgDestageOut = bs_destageData.outLun[ dgHandle ];
looks like this might access outLun[BS_CFG_DRIVE_GROUPS] which is
out-of-bounds.
Richard.
You are correct, and when I change outLun[] to be size
BS_CFG_DRIVE_GROUPS+1, the generated asm looks like it will account for
dgHandle in the while() loop. I will pass this back to our development
team to get a proper fix.
Now, the followon: Something in the compiler/optimizer recognized this
out of bounds situation - should a warning have been emitted? Or are
there ambiguities which make a warning generation here inappropriate?
And an additional question: It still seems wrong to omit the dgHandle
check from the while() condition vs. leaving it in and letting the code
access beyond the end of the array. Is this one of those areas where if
there's a bug in the code all bets are off and your mileage may vary?
Thanks to everyone who helped me out here.
Mark