$ gcc -O2 input.c -o input $ ./input input: input.c:36: main: Assertion `s.buffer_position == s.buffer_end' failed. The loop loses the increment of s.buffer_position.
Created attachment 12039 [details] Testcase
I bet this is a loop.c bug.
-floop-optimize2 doesn't help.
Looks like introduced during the tree-ssa merge.
Confirmed. The problem is probably latent on mainline. check_header is being miscompiled, -O -fno-loop-optimize2 -fno-loop-optimize -fno-branch-count-reg is enough to trigger the bug (i.e. no loop bug). extern void abort(void); struct input_ty { unsigned char *buffer_position; unsigned char *buffer_end; }; int input_getc_complicated (struct input_ty *x) { return 0; } int check_header (struct input_ty *deeper) { unsigned len; for (len = 0; len < 6; len++) if (((deeper)->buffer_position < (deeper)->buffer_end ? *((deeper)->buffer_position)++ : input_getc_complicated((deeper))) < 0) return 0; return 1; } struct input_ty s; unsigned char b[6]; int main (void) { s.buffer_position = b; s.buffer_end = b + sizeof b; if (!check_header(&s)) return 1; if (s.buffer_position != s.buffer_end) abort(); return 0; } it looks like ifcvt messes up in pass 3 and puts the post-inc in the cond-exec block.
> it looks like ifcvt messes up in pass 3 and puts the post-inc in the > cond-exec block. It's actually the combiner that wrongly ditches the post-inc, at least with the last set of options you posted. Amazingly enough, on the 4.1 branch, the combiner is the first pass which deduces that *((deeper)->buffer_position)++ < 0 is always false. In particular, we have this little gem in t97.final_cleanup unsigned char * D.1386; _Bool iftmp.0; iftmp.0 = (int) *D.1386 < 0; even at -O2! This is optimized on mainline, which hides the problem there. Fixing...
Subject: Bug 28636 Author: ebotcazou Date: Sun Sep 10 21:27:36 2006 New Revision: 116827 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116827 Log: PR rtl-optimization/28636 * combine.c (force_to_mode): Test for side-effects before substituting by zero. (simplify_shift_const): Likewise for zero or other constants. Added: trunk/gcc/testsuite/gcc.c-torture/execute/20060910-1.c Modified: trunk/gcc/ChangeLog trunk/gcc/combine.c trunk/gcc/testsuite/ChangeLog
Subject: Bug 28636 Author: ebotcazou Date: Sun Sep 10 21:28:03 2006 New Revision: 116828 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116828 Log: PR rtl-optimization/28636 * combine.c (force_to_mode): Test for side-effects before substituting by zero. (simplify_shift_const): Likewise for zero or other constants. Added: branches/gcc-4_1-branch/gcc/testsuite/gcc.c-torture/execute/20060910-1.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/combine.c branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
Subject: Bug 28636 Author: ebotcazou Date: Sun Sep 10 21:28:39 2006 New Revision: 116829 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=116829 Log: PR rtl-optimization/28636 * combine.c (force_to_mode): Test for side-effects before substituting by zero. (simplify_shift_const): Likewise for zero or other constants. Added: branches/gcc-4_0-branch/gcc/testsuite/gcc.c-torture/execute/20060910-1.c Modified: branches/gcc-4_0-branch/gcc/ChangeLog branches/gcc-4_0-branch/gcc/combine.c branches/gcc-4_0-branch/gcc/testsuite/ChangeLog
Fixed everywhere.