http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58715
Bug ID: 58715 Summary: Missed loop condition optimization opportunity Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ryao at gentoo dot org Created attachment 30995 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=30995&action=edit lzjb_decompress code from ZFS Here is a snippet of the lzjb implementation from Open ZFS showing a change that tightens a loop condition in a frequently executed loop: - while (--mlen >= 0 && dst < d_end) + if (mlen > (d_end - dst)) + mlen = d_end - dst; + while (--mlen >= 0) *dst++ = *cpy++; In the original version, dst increments toward d_end while mlen decrements toward 0 on each loop iteration. Eventually, one will reach its termination condition. Nothing else touches mlen, so it is safe to do mlen = MIN(mlen, d_end - dst) before the loop and drop the ` && dst < d_end` part of the condition. Even if it were used elsewhere, a temporary could be used to store the minimum of the two. The assembly generated by GCC 4.8.1 on the original evaluates both conditions on each iteration while the assembly generated for the patched version does not. In addition, loop unrolling is done on the patched version on -O3 while the original sees no unrolling at any optimization level.