http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59429
Bug ID: 59429 Summary: Missed optimization opportunity in qsort-style comparison functions Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: minor Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jengelh at inai dot de The following code: extern int comLG(int, int); extern int comLE(int, int); extern int comEL(int, int); extern int comEG(int, int); extern int comGL(int, int); extern int comGE(int, int); int comLG(int a, int b) { return (a < b) ? -1 : (a > b) ? 1 : 0; } int comLE(int a, int b) { return (a < b) ? -1 : (a == b) ? 0 : 1; } int comEL(int a, int b) { return (a == b) ? 0 : (a < b) ? -1 : 1; } int comEG(int a, int b) { return (a == b) ? 0 : (a > b) ? 1 : -1; } int comGL(int a, int b) { return (a > b) ? 1 : (a < b) ? -1 : 0; } int comGE(int a, int b) { return (a > b) ? 1 : (a == b) ? 0 : -1; } when compiled with: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.8/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 --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.8 --enable-ssp --disable-libssp --disable-plugin --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --enable-linker-build-id --program-suffix=-4.8 --enable-linux-futex --without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux Thread model: posix gcc version 4.8.1 20130909 [gcc-4_8-branch revision 202388] (SUSE Linux) yields object code with different realizations and sizes. What I observe: $ gcc -Os -c cmp.c (also shows with -O3) $ readelf -s cmp.o Num: Value Size Type Bind Vis Ndx Name 8: 0000000000000000 16 FUNC GLOBAL DEFAULT 1 comLG 9: 0000000000000010 16 FUNC GLOBAL DEFAULT 1 comLE 10: 0000000000000020 18 FUNC GLOBAL DEFAULT 1 comEL 11: 0000000000000032 18 FUNC GLOBAL DEFAULT 1 comEG 12: 0000000000000044 18 FUNC GLOBAL DEFAULT 1 comGL 13: 0000000000000056 18 FUNC GLOBAL DEFAULT 1 comGE $ objdump -d cmp.o -Mintel 0000000000000000 <comLG>: 0: 31 d2 xor edx,edx 2: 39 f7 cmp edi,esi 4: b8 ff ff ff ff mov eax,0xffffffff 9: 0f 9f c2 setg dl c: 0f 4d c2 cmovge eax,edx f: c3 ret 0000000000000010 <comLE>: 10: 31 d2 xor edx,edx 12: 39 f7 cmp edi,esi 14: b8 ff ff ff ff mov eax,0xffffffff 19: 0f 95 c2 setne dl 1c: 0f 4d c2 cmovge eax,edx 1f: c3 ret 0000000000000020 <comEL>: 20: 39 f7 cmp edi,esi 22: 74 0b je 2f <comEL+0xf> 24: 0f 9d c0 setge al 27: 0f b6 c0 movzx eax,al 2a: 8d 44 00 ff lea eax,[rax+rax*1-0x1] 2e: c3 ret 2f: 31 c0 xor eax,eax 31: c3 ret 0000000000000032 <comEG>: 32: 39 f7 cmp edi,esi 34: 74 0b je 41 <comEG+0xf> 36: 0f 9f c0 setg al 39: 0f b6 c0 movzx eax,al 3c: 8d 44 00 ff lea eax,[rax+rax*1-0x1] 40: c3 ret 41: 31 c0 xor eax,eax 43: c3 ret 0000000000000044 <comGL>: 44: 39 f7 cmp edi,esi 46: b8 01 00 00 00 mov eax,0x1 4b: 7f 08 jg 55 <comGL+0x11> 4d: 0f 9c c0 setl al 50: 0f b6 c0 movzx eax,al 53: f7 d8 neg eax 55: c3 ret 0000000000000056 <comGE>: 56: 39 f7 cmp edi,esi 58: b8 01 00 00 00 mov eax,0x1 5d: 7f 08 jg 67 <comGE+0x11> 5f: 0f 95 c0 setne al 62: 0f b6 c0 movzx eax,al 65: f7 d8 neg eax 67: c3 ret What I expected instead: All functions to have the same asm.