[Bug tree-optimization/40679] Optimizer handles loops with volatiles and post-incr. wrong
--- Comment #8 from bastian dot schick at sciopta dot com 2009-07-08 13:06 --- (In reply to comment #6) > (In reply to comment #2) > > Replacing *tbl++ by tbl[i] gives this ARM code: > > .L2: > > mov r3, #10 > > str r3, [r2], #4 > > cmp r2, #0 > > bne .L2 > > bx lr > > > > See, gcc knows about the wrapping but still the *tbl++ version misses the > > end-condition which is the bug. > > The difference is that in the tbl[i] version there will not be a wraparound at > runtime because &tbl[i] for i == 64 is never computed, while in the *tbl++ > version the iteration with i == 63 will do tbl++ moving tbl from -4U to 0 > before the loop termination test, which triggers undefined behaviour. Ok fine, but why does it generate correct code if not using volatile for the pointer ?! mvn r2, #251 .L2: mov r3, #10 str r3, [r2, #-4] add r2, r2, #4 cmp r2, #4 bne .L2 bx lr Strange, no post-increment code is generated. The 68k version still uses post-increment and voilĂ , endless-loop. Also see the code for the tbl[i] version, the pointer still wraps. I suspect following: The test for 0 is removed maybe because the post-increment is defined to change flags( which it isn't). Since there is no test, the next optimization changes a "jump not zero" to an "jump always". -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40679
[Bug rtl-optimization/40679] Optimizer handles loops with volatiles and post-incr. wrong
--- Comment #4 from bastian dot schick at sciopta dot com 2009-07-08 09:06 --- (In reply to comment #3) > On trunk with -fno-tree-vrp I see the correct code being generated. It seems to be related to Bug #30785 (test for null pointer). -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40679
[Bug rtl-optimization/40679] Optimizer handles loops with volatiles and post-incr. wrong
--- Comment #2 from bastian dot schick at sciopta dot com 2009-07-08 08:24 --- (In reply to comment #1) > > Sent from my iPhone Oh, dude (which one :-) > On Jul 8, 2009, at 12:32 AM, "bastian dot schick at sciopta dot com" > > wrote: > > > If the following code is compiled with -Os for ARM or ColdFire, the > > exit > > condition for the loop is removed. > > Replacing *tbl++ with tbl[i] or using unsigned long instead of > > volatile > > unsigned long does not show the problem. > > I suspect the post-increment optimization to be the problem, because > > the > > PowerPC version does not show the problem. > > Also: Using a different start-address for tbl, does not show the > > problem. > > It looks more like a wrapping issue. 4*64 = 256. So we go from -256u > to 0 which causes wrapping of the pointer which is undefined and If so, it should not be used, but it seems to be a new optimization as 3.4.4 does not use it. > therefor I think gcc is doing the correct thing (If got my numbers > correct). Replacing *tbl++ by tbl[i] gives this ARM code: .L2: mov r3, #10 str r3, [r2], #4 cmp r2, #0 bne .L2 bx lr See, gcc knows about the wrapping but still the *tbl++ version misses the end-condition which is the bug. Addenum: x86-gcc 4.3.3 (openSUSE 10.0) has the same problem. Compiling with -O, gives correct code with *tbl++ : .L2: mov r3, #10 str r3, [r2], #4 cmp r2, #0 bne .L2 bx lr -- bastian dot schick at sciopta dot com changed: What|Removed |Added ---------------- CC| |bastian dot schick at ||sciopta dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40679
[Bug rtl-optimization/40679] New: Optimizer handles loops with volatiles and post-incr. wrong
If the following code is compiled with -Os for ARM or ColdFire, the exit condition for the loop is removed. Replacing *tbl++ with tbl[i] or using unsigned long instead of volatile unsigned long does not show the problem. I suspect the post-increment optimization to be the problem, because the PowerPC version does not show the problem. Also: Using a different start-address for tbl, does not show the problem. The problem has been reported also for 4.4.0. typedef volatile unsigned long __vu32; void bs() { int i; __vu32 *tbl = (__vu32 *)0xff00; for(i = 0; i < 64; ++i){ //-> tbl[i] = (__vu32)10; *tbl++ = (__vu32)10; } } Cmd-line: arm-none-eabi-gcc -S -Os t.c Output: .cpu arm7tdmi .fpu softvfp .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 1 .eabi_attribute 30, 4 .eabi_attribute 18, 4 .file "t.c" .text .align 2 .global bs .type bs, %function bs: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. mvn r2, #255 .L2: mov r3, #10 str r3, [r2], #4 b .L2 .size bs, .-bs .ident "GCC: (Sourcery G++ Lite 2008q3-39) 4.3.2" -- Summary: Optimizer handles loops with volatiles and post-incr. wrong Product: gcc Version: 4.3.2 Status: UNCONFIRMED Severity: major Priority: P3 Component: rtl-optimization AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bastian dot schick at sciopta dot com GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-mingw32 GCC target triplet: i686-mingw32 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40679