Public bug reported:

default optimizations cause issues with this kind of operation:

dingus.rip += doodle(&dingus);

where the call to doodle() mutates dingus.rip

The produced assembly will use stale data and simply overwrite the
mutation with the original value.  the resulting code simplifies to this
pseudo code:

dingus.rip = 0
doodle(&dingus) ===  dingus->rip = 4; return 0;
dingus.rip = 0 + return value of doodle()

which is not correct, since it should simplify to this
dingus.rip = 0
doodle(&dingus) ===  dingus->rip = 4; return 0;
dingus.rip = dingus.rip + return value of doodle()


user@hostname:~/$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4

user@hostname:~/$ gcc -o test test.c
user@hostname:~/$ ./test
0

Expected result: 4


test.c

#include <stdio.h>

struct jit {
        unsigned long long rip;
};

unsigned int doodle(struct jit * dingus)
{
        dingus->rip = 0x4;
        return 0;
}

void tryme(void)
{
        struct jit dingus;
        dingus.rip = 0;

        dingus.rip += doodle(&dingus);
        printf("%llx\n", dingus.rip);
        return;
}

int main(void)
{
        tryme();
}


objdump -D -Mintel ./test


000000000040052d <doodle>:
  40052d:       55                      push   rbp
  40052e:       48 89 e5                mov    rbp,rsp
  400531:       48 89 7d f8             mov    QWORD PTR [rbp-0x8],rdi
  400535:       48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
  400539:       48 c7 00 04 00 00 00    mov    QWORD PTR [rax],0x4
  400540:       b8 00 00 00 00          mov    eax,0x0
  400545:       5d                      pop    rbp
  400546:       c3                      ret    

0000000000400547 <tryme>:
  400547:       55                      push   rbp
  400548:       48 89 e5                mov    rbp,rsp
  40054b:       53                      push   rbx
  40054c:       48 83 ec 18             sub    rsp,0x18
  400550:       48 c7 45 e0 00 00 00    mov    QWORD PTR [rbp-0x20],0x0
  400557:       00 
  400558:       48 8b 5d e0             mov    rbx,QWORD PTR [rbp-0x20]
  40055c:       48 8d 45 e0             lea    rax,[rbp-0x20]
  400560:       48 89 c7                mov    rdi,rax
  400563:       e8 c5 ff ff ff          call   40052d <doodle>
  400568:       89 c0                   mov    eax,eax
  40056a:       48 01 d8                add    rax,rbx
  40056d:       48 89 45 e0             mov    QWORD PTR [rbp-0x20],rax
  400571:       48 8b 45 e0             mov    rax,QWORD PTR [rbp-0x20]
  400575:       48 89 c6                mov    rsi,rax
  400578:       bf 24 06 40 00          mov    edi,0x400624
  40057d:       b8 00 00 00 00          mov    eax,0x0
  400582:       e8 89 fe ff ff          call   400410 <printf@plt>
  400587:       90                      nop
  400588:       48 83 c4 18             add    rsp,0x18
  40058c:       5b                      pop    rbx
  40058d:       5d                      pop    rbp
  40058e:       c3                      ret    

000000000040058f <main>:
  40058f:       55                      push   rbp
  400590:       48 89 e5                mov    rbp,rsp
  400593:       e8 af ff ff ff          call   400547 <tryme>
  400598:       5d                      pop    rbp
  400599:       c3                      ret    
  40059a:       66 0f 1f 44 00 00       nop    WORD PTR [rax+rax*1+0x0]

** Affects: gcc-4.8 (Ubuntu)
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to gcc-4.8 in Ubuntu.
https://bugs.launchpad.net/bugs/1773239

Title:
  Optimization Error:  += operation while mutating the destination on
  the right hand side

Status in gcc-4.8 package in Ubuntu:
  New

Bug description:
  default optimizations cause issues with this kind of operation:

  dingus.rip += doodle(&dingus);

  where the call to doodle() mutates dingus.rip

  The produced assembly will use stale data and simply overwrite the
  mutation with the original value.  the resulting code simplifies to
  this pseudo code:

  dingus.rip = 0
  doodle(&dingus) ===  dingus->rip = 4; return 0;
  dingus.rip = 0 + return value of doodle()

  which is not correct, since it should simplify to this
  dingus.rip = 0
  doodle(&dingus) ===  dingus->rip = 4; return 0;
  dingus.rip = dingus.rip + return value of doodle()


  
  user@hostname:~/$ gcc --version
  gcc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4

  user@hostname:~/$ gcc -o test test.c
  user@hostname:~/$ ./test
  0

  Expected result: 4

  
  test.c

  #include <stdio.h>

  struct jit {
        unsigned long long rip;
  };

  unsigned int doodle(struct jit * dingus)
  {
        dingus->rip = 0x4;
        return 0;
  }

  void tryme(void)
  {
        struct jit dingus;
        dingus.rip = 0;

        dingus.rip += doodle(&dingus);
        printf("%llx\n", dingus.rip);
        return;
  }

  int main(void)
  {
        tryme();
  }

  
  objdump -D -Mintel ./test

  
  000000000040052d <doodle>:
    40052d:     55                      push   rbp
    40052e:     48 89 e5                mov    rbp,rsp
    400531:     48 89 7d f8             mov    QWORD PTR [rbp-0x8],rdi
    400535:     48 8b 45 f8             mov    rax,QWORD PTR [rbp-0x8]
    400539:     48 c7 00 04 00 00 00    mov    QWORD PTR [rax],0x4
    400540:     b8 00 00 00 00          mov    eax,0x0
    400545:     5d                      pop    rbp
    400546:     c3                      ret    

  0000000000400547 <tryme>:
    400547:     55                      push   rbp
    400548:     48 89 e5                mov    rbp,rsp
    40054b:     53                      push   rbx
    40054c:     48 83 ec 18             sub    rsp,0x18
    400550:     48 c7 45 e0 00 00 00    mov    QWORD PTR [rbp-0x20],0x0
    400557:     00 
    400558:     48 8b 5d e0             mov    rbx,QWORD PTR [rbp-0x20]
    40055c:     48 8d 45 e0             lea    rax,[rbp-0x20]
    400560:     48 89 c7                mov    rdi,rax
    400563:     e8 c5 ff ff ff          call   40052d <doodle>
    400568:     89 c0                   mov    eax,eax
    40056a:     48 01 d8                add    rax,rbx
    40056d:     48 89 45 e0             mov    QWORD PTR [rbp-0x20],rax
    400571:     48 8b 45 e0             mov    rax,QWORD PTR [rbp-0x20]
    400575:     48 89 c6                mov    rsi,rax
    400578:     bf 24 06 40 00          mov    edi,0x400624
    40057d:     b8 00 00 00 00          mov    eax,0x0
    400582:     e8 89 fe ff ff          call   400410 <printf@plt>
    400587:     90                      nop
    400588:     48 83 c4 18             add    rsp,0x18
    40058c:     5b                      pop    rbx
    40058d:     5d                      pop    rbp
    40058e:     c3                      ret    

  000000000040058f <main>:
    40058f:     55                      push   rbp
    400590:     48 89 e5                mov    rbp,rsp
    400593:     e8 af ff ff ff          call   400547 <tryme>
    400598:     5d                      pop    rbp
    400599:     c3                      ret    
    40059a:     66 0f 1f 44 00 00       nop    WORD PTR [rax+rax*1+0x0]

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gcc-4.8/+bug/1773239/+subscriptions

-- 
Mailing list: https://launchpad.net/~touch-packages
Post to     : touch-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~touch-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to