https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79351

            Bug ID: 79351
           Summary: Invalid tree PRE optimization around compound literal
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: wellons at nullprogram dot com
  Target Milestone: ---

Created attachment 40659
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40659&action=edit
Demonstrates an invalid -ftree-pre optimization

GCC's -ftree-pre optimization incorrectly optimizes compound literals. I have
verified this bug in 6.3.0 (x86-64), 5.4.0 (AArch64), and 4.9.2 (x86-64).

Attached is a C program demonstrating the bug. When compiled with "-O1
-ftree-pre" the resulting program is miscompiled and produces incorrect output.
This only happens when the compound literal is used in the assignment
(-DENABLE_GCC_BUG=1, line 24), not under an identical memset() (line 26).

The example's header explains how to reproduce the bug for yourself:

    $ gcc -std=c99 -O1 -ftree-pre -DENABLE_GCC_BUG=0 -o valid  example.c
    $ gcc -std=c99 -O1 -ftree-pre -DENABLE_GCC_BUG=1 -o broken example.c
    $ echo bookkeeper | ./valid XXYYZZ
    bookkeeper
    $ echo bookkeeper | ./broken XXYYZZ
    $

The bug manifest at line 29, where the increment operation is "optimized" away
into a constant 1 assignment. Here's the relevant x86-64 assembly for line 29
in the memset() version, which behaves correctly:

    movsx   rax, DWORD PTR states[rip]
    lea     edx, [rax+1]
    mov     DWORD PTR states[rip], edx
    movsx   rdx, BYTE PTR [r9+rax]

The 32-bit signed integer is read into rax, incremented into edx, and written
back. The original integer, still in rax, is also used in the array index off
r9.

Here's the broken version of this line, when the compound literal was used:

    mov     DWORD PTR states[rip], 1
    movsx   rdx, BYTE PTR [r9]

The integer on the struct is incorrectly assumed to be zero and is not read,
instead it's clobbered by a constant 1. Also because of the zero assumption,
it's not used as an array index off r9.

Here's the example under the Compiler Explorer in case that's helpful:
https://godbolt.org/g/ILmwSh

Reply via email to