On Tue, 2005-11-15 at 13:31 -0800, Joe Buck wrote: > On Tue, Nov 15, 2005 at 02:15:44PM -0700, Jeffrey A Law wrote: > > > > So, is it just me or does execute/930529-1.c invoke undefined or > > implementation defined behavior due to its reliance upon overflow > > behavior for signed types? > > > > In particular look at the control for the second loop: > > > > int i; > > [ ... ] > > > > for (i = ((unsigned) ~0 >> 1) - 3; i <= ((unsigned) ~0 >> 1) + 3; i++) > > > > > > i <= ((unsigned)~0>>1) + 3 > > > > Seems like it overflows to me, or would cause "i" to have to > > overflow to terminate the loop. > > There is no overflow in the test; the RHS is an unsigned expression > (mix signed and unsigned, you get unsigned). This means that the > termination test is equivalent to > > unsigned(i) <= ((unsigned)~0>>1)+3 > or > unsigned(i) <= (~0U>>1U)+3U Makes sense.
> However, the test does rely on the autoincrement wrapping around; > specifically that i++ sets i to (int)(((unsigned)i)+1U). And after further thought, I came to the same conclusion -- it's the wrap-around behavior for "i" that's the problem. And that's precisely where things go wrong in VRP. Basically if the for loop is turned into a do-while loop (entry condition is a compile-time constant), then VRP will determine that "i"'s range is [2147483644,+INF]. VRP then determines that the range of the temporary created to convert "i" into an unsigned value after incrementing "i" has the range [2147483645,2147483647] At which point things fall apart because we're not capturing the wrap-around effect of "i" in the converted value. > Perhaps the test could be rewritten as It might be even easier to just add -fwrapv and leave the test alone. I don't know if that compromises the test or not -- it's too old and not a test I'm terribly familiar with. jeff