Sometimes GCC generate code at end of function: cmovge %eax,%edi mov %edi,%eax retq but faster: cmovl %edi,%eax retq Example: # cat test.c #define MX 0 #define LIM 7 char char_char(char m) {if(m>LIM) return(MX); return(m);} char char_int(int m) {if(m>LIM) return(MX); return(m);} char char_uint(unsigned int m) {if(m>LIM) return(MX); return(m);} char char_long(long m) {if(m>LIM) return(MX); return(m);} char char_ulong(unsigned long m) {if(m>LIM) return(MX); return(m);} int int_char(char m) {if(m>LIM) return(MX); return(m);} int int_int(int m) {if(m>LIM) return(MX); return(m);} // Nonoptimal int int_uint(unsigned int m) {if(m>LIM) return(MX); return(m);} int int_long(long m) {if(m>LIM) return(MX); return(m);} int int_ulong(unsigned long m) {if(m>LIM) return(MX); return(m);} unsigned int uint_char(char m) {if(m>LIM) return(MX); return(m);} unsigned int uint_int(int m) {if(m>LIM) return(MX); return(m);} unsigned int uint_uint(unsigned int m) //Nonoptimal {if(m>LIM) return(MX); return(m);} unsigned int uint_long(long m) {if(m>LIM) return(MX); return(m);} unsigned int uint_ulong(unsigned long m) {if(m>LIM) return(MX); return(m);} long long_char(char m) {if(m>LIM) return(MX); return(m);} long long_int(int m) {if(m>LIM) return(MX); return(m);} long long_uint(unsigned int m) {if(m>LIM) return(MX); return(m);} long long_long(long m) //Nonoptimal {if(m>LIM) return(MX); return(m);} long long_ulong(unsigned long m) {if(m>LIM) return(MX); return(m);} unsigned long ulong_char(char m) {if(m>LIM) return(MX); return(m);} unsigned long ulong_int(int m) {if(m>LIM) return(MX); return(m);} unsigned long ulong_uint(unsigned int m) {if(m>LIM) return(MX); return(m);} unsigned long ulong_long(long m) {if(m>LIM) return(MX); return(m);} unsigned long ulong_ulong(unsigned long m) //Nonoptimal {if(m>LIM) return(MX); return(m);} # gcc -o t test.c -O2 -c # objdump -d t t: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <char_char>: 0: 89 f8 mov %edi,%eax 2: 40 80 ff 08 cmp $0x8,%dil 6: ba 00 00 00 00 mov $0x0,%edx b: 0f 4d c2 cmovge %edx,%eax <--- It's ok! Optimal e: c3 retq f: 90 nop <skip...> 0000000000000060 <int_int>: 60: 83 ff 08 cmp $0x8,%edi 63: b8 00 00 00 00 mov $0x0,%eax 68: 0f 4d f8 cmovge %eax,%edi <--- Nonoptimal 6b: 89 f8 mov %edi,%eax <--- Nonoptimal 6d: c3 retq 6e: 66 90 xchg %ax,%ax <skip...> 00000000000000c0 <uint_uint>: c0: 83 ff 08 cmp $0x8,%edi c3: b8 00 00 00 00 mov $0x0,%eax c8: 0f 43 f8 cmovae %eax,%edi <--- Nonoptimal cb: 89 f8 mov %edi,%eax <--- Nonoptimal cd: c3 retq ce: 66 90 xchg %ax,%ax <skip...> 0000000000000120 <long_long>: 120: 48 83 ff 08 cmp $0x8,%rdi 124: b8 00 00 00 00 mov $0x0,%eax 129: 48 0f 4d f8 cmovge %rax,%rdi <--- Nonoptimal 12d: 48 89 f8 mov %rdi,%rax <--- Nonoptimal 130: c3 retq <skip...> 0000000000000190 <ulong_ulong>: 190: 48 83 ff 08 cmp $0x8,%rdi 194: b8 00 00 00 00 mov $0x0,%eax 199: 48 0f 43 f8 cmovae %rax,%rdi <--- Nonoptimal 19d: 48 89 f8 mov %rdi,%rax <--- Nonoptimal 1a0: c3 retq
There is no bug for current trunk. So bug fixed.
(In reply to comment #1) > There is no bug for current trunk. So bug fixed. Not really, the move insn is moved to the beginning of the function: 0000000000000060 <int_int>: 60: 89 f8 mov %edi,%eax 62: 83 ff 08 cmp $0x8,%edi 65: ba 00 00 00 00 mov $0x0,%edx 6a: 0f 4d c2 cmovge %edx,%eax 6d: c3 retq
> Not really, the move insn is moved to the beginning of the function: > 0000000000000060 <int_int>: > 60: 89 f8 mov %edi,%eax > 62: 83 ff 08 cmp $0x8,%edi > 65: ba 00 00 00 00 mov $0x0,%edx > 6a: 0f 4d c2 cmovge %edx,%eax > 6d: c3 retq You are right. Bug reopen.