Bug 40072 - Nonoptimal code - CMOVxx %eax,%edi; mov %edi,%eax; retq
Summary: Nonoptimal code - CMOVxx %eax,%edi; mov %edi,%eax; retq
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.4.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization, ra
Depends on:
Blocks:
 
Reported: 2009-05-08 16:04 UTC by Vladimir Volynsky
Modified: 2023-08-08 01:26 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-*-*
Build:
Known to work:
Known to fail: 8.2.0
Last reconfirmed: 2023-08-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Volynsky 2009-05-08 16:04:10 UTC
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
Comment 1 Vladimir Volynsky 2009-05-09 12:02:51 UTC
There is no bug for current trunk. So bug fixed.
Comment 2 Uroš Bizjak 2009-05-09 21:37:59 UTC
(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   
Comment 3 Vladimir Volynsky 2009-05-10 16:09:15 UTC
> 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.