This is very related to this bug (43892):
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43892

There are many ways to try to add with carry - and difficult to catch them all.
I really 'tried to think like a compiler' when I wrote the following
(C++ Intel 32bit code) code:
(not even strict correctly c++. It won't work with AMD64 - since long long is
64 bit - just like unsigned long - and __int128 isn't quite there yet).

// Data structures:
struct Skew1Even
{
  unsigned long long data; // This could be an array 
  unsigned long unused;
};

struct Skew2Odd
{
  unsigned long unused;
  unsigned long long data;  // This could be an array
};

struct ULongLongLong
{
  union
  {
    unsigned long m_data[3];
    Skew1 m_rep1;
    Skew2 m_rep2;
  };
  ULongLongLong()
  {
    m_data[0]=0;
    m_data[1]=0;
    m_data[2]=0;
  }
//  void print() {  std::cout << m_data[0] << "," << m_data[1] << "," << //
m_data[2] << "\n";}
  void addtest(const ULongLongLong &b); // operator += 
};

The addtest is the important part:
void ULongLongLong::addtest(const ULongLongLong &b)
{
//  if (this==&b) // removed to make the example easier
//    doTimes2();    
  m_rep1.data+=b.m_data[0];
  m_rep2.data+=b.m_data[1];
  m_data[2]+=b.m_data[2];
}

The main point in my code is also in the compiled code (but not used by the
compiler). What I hoped to happen was that gcc saw that adding 0 with carry
'quickly' followed by a normal add would be the same as just the last add (but)
with carry.

I however only get the code:
.globl _ZN13ULongLongLong7addtestERKS_
        .type   _ZN13ULongLongLong7addtestERKS_, @function
_ZN13ULongLongLong7addtestERKS_:
.LFB964:
        .cfi_startproc
        .cfi_personality 0x0,__gxx_personality_v0
        pushl   %ebp
        .cfi_def_cfa_offset 8
        movl    %esp, %ebp
        .cfi_offset 5, -8
        .cfi_def_cfa_register 5
        movl    12(%ebp), %edx
        movl    8(%ebp), %eax
        pushl   %ebx
        xorl    %ebx, %ebx
        .cfi_offset 3, -12
        movl    (%edx), %ecx
        addl    %ecx, (%eax)
        adcl    %ebx, 4(%eax)
        xorl    %ebx, %ebx
        movl    4(%edx), %ecx
        addl    %ecx, 4(%eax)
        adcl    %ebx, 8(%eax)
        movl    8(%edx), %edx
        addl    %edx, 8(%eax)
        popl    %ebx
        popl    %ebp
        ret
        .cfi_endproc

What I wanted was this code:
globl _ZN13ULongLongLong7addtestERKS_
        .type   _ZN13ULongLongLong7addtestERKS_, @function
_ZN13ULongLongLong7addtestERKS_:
.LFB1001:
        .cfi_startproc
        .cfi_personality 0x0,__gxx_personality_v0
        pushl   %ebp
        .cfi_def_cfa_offset 8
        movl    %esp, %ebp
        .cfi_offset 5, -8
        .cfi_def_cfa_register 5
        movl    12(%ebp), %edx
        movl    8(%ebp), %eax
/*      pushl   %ebx */  /* not needed anymore - we don't use it */
/*      xorl    %ebx, %ebx   No need to reset ebx */
        .cfi_offset 3, -12
        movl    (%edx), %ecx
        addl    %ecx, (%eax)
/*      adcl    %ebx, 4(%eax)   */
/*      xorl    %ebx, %ebx     Why do it at all - ebx was already 0 !?*/
        movl    4(%edx), %ecx
        adcl    %ecx, 4(%eax) /* modified addl to adcl */
/*      adcl    %ebx, 8(%eax)  */
        movl    8(%edx), %edx
        adcl    %edx, 8(%eax)  /* modified addl to adcl */
/*      popl    %ebx */
        popl    %ebp
        ret
        .cfi_endproc

However - the code I want is:
Note: It seems like adding could be replaced with subtraction.

It may still be better to make carry work a bit more in general - and I
understand that this might be a won't fix - especially if you provide a clear
way to add with carry in general.

However this might just be a much easier peephole(-like) optimization.

PS: Thanks for a really great compiler.


-- 
           Summary: Add with carry - missed optimization
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: tmartsum at gmail dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45548

Reply via email to