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.

Reply via email to