https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70042
Bug ID: 70042 Summary: Room for optimization of x+1>y vs x>=y Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: jengelh at inai dot de Target Milestone: --- $ gcc -v Using built-in specs. COLLECT_GCC=gcc-6 COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/6/lto-wrapper Target: x86_64-suse-linux Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada,go --enable-checking=yes --with-gxx-include-dir=/usr/include/c++/6 --enable-ssp --disable-libssp --disable-libvtv --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --with-default-libstdcxx-abi=gcc4-compatible --enable-version-specific-runtime-libs --enable-linker-build-id --enable-linux-futex --program-suffix=-6 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux --host=x86_64-suse-linux Thread model: posix gcc version 6.0.0 20160202 (experimental) [trunk revision 233076] (SUSE Linux) $ cat g1.c geq.c #include <string.h> int main(int argc, char **argv) { return strlen(argv[0])+1 > 108; } #include <string.h> int main(int argc, char **argv) { return strlen(argv[0]) >= 108; } $ gcc-6 g1.c -Wall -O2 -c geq.c $ objdump -d g1.o geq.o 0000000000000000 <main>: //g1 0: 48 83 ec 08 sub $0x8,%rsp 4: 48 8b 3e mov (%rsi),%rdi 7: e8 00 00 00 00 callq c <main+0xc> c: 48 83 c0 01 add $0x1,%rax 10: 48 83 f8 6c cmp $0x6c,%rax 14: 0f 97 c0 seta %al 17: 48 83 c4 08 add $0x8,%rsp 1b: 0f b6 c0 movzbl %al,%eax 1e: c3 retq 0000000000000000 <main>: //geq 0: 48 83 ec 08 sub $0x8,%rsp 4: 48 8b 3e mov (%rsi),%rdi 7: e8 00 00 00 00 callq c <main+0xc> c: 48 83 f8 6b cmp $0x6b,%rax 10: 0f 97 c0 seta %al 13: 48 83 c4 08 add $0x8,%rsp 17: 0f b6 c0 movzbl %al,%eax 1a: c3 retq The x+1>=y variant uses more code, but does not have to. In contrast, with -Os: 0000000000000000 <main>: //g1 0: 48 8b 3e mov (%rsi),%rdi 3: 31 c0 xor %eax,%eax 5: 48 83 c9 ff or $0xffffffffffffffff,%rcx 9: f2 ae repnz scas %es:(%rdi),%al b: 31 c0 xor %eax,%eax d: 48 f7 d1 not %rcx 10: 48 83 f9 6c cmp $0x6c,%rcx 14: 0f 97 c0 seta %al 17: c3 retq 0000000000000000 <main>: //geq 0: 48 8b 3e mov (%rsi),%rdi 3: 31 c0 xor %eax,%eax 5: 48 83 c9 ff or $0xffffffffffffffff,%rcx 9: f2 ae repnz scas %es:(%rdi),%al b: 48 89 c8 mov %rcx,%rax e: 48 f7 d0 not %rax 11: 48 ff c8 dec %rax 14: 48 83 f8 6b cmp $0x6b,%rax 18: 0f 97 c0 seta %al 1b: 0f b6 c0 movzbl %al,%eax 1e: c3 retq the reverse is true, x>=y using more code but does not have to.