<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Loses aliasing information through union when rewriting into conditional move"
   href="https://bugs.llvm.org/show_bug.cgi?id=33278">33278</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Loses aliasing information through union when rewriting into conditional move
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>4.0
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>steinar+llvm@gunderson.no
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Given clang 4.0 rc1:

atum17:~> clang-4.0 --version
clang version 4.0.1-+rc1-1 (tags/RELEASE_401/rc1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

The following minimal example (reduced from string-to-double parsing code
in MySQL) is miscompiled, seemingly because the compiler loses track of
aliasing information when converting the add into a conditional operation
and thinks “da” was never changed:

atum17:~> cat test.cc
#include <stdio.h>

typedef union { double d; unsigned int L[2]; } U;

double func(int k)
{
  U da, db;

  da.d = 1.453125;
  db.d = 1.0;
  if (k > 0) {
    da.L[1] += k;
  } else {
    k= -k;
    db.L[1] += k;
  }
  return da.d;
}

int main(void)
{
  printf("%f\n", func(0x300000));
}

atum17:~> clang-4.0 -O2 -o test test.cc
atum17:~> ./test
1.453125
atum17:~> clang-4.0 -O2 -fno-strict-aliasing -o test test.cc
atum17:~> ./test                                            
11.625000

As I understand it, accessing through an union like this is not a
strict aliasing violation since C11 and C++11, so the code should
give the same answer in both cases. Clang 3.9 and GCC 7.1.0 gives
the correct answer. The generated x86 code is:

00000000004004f0 <_Z4funci>:
  4004f0:       89 f8                   mov    %edi,%eax
  4004f2:       f7 d8                   neg    %eax
  4004f4:       0f 4c c7                cmovl  %edi,%eax
  4004f7:       48 b9 00 00 00 00 00    movabs $0x3ff7400000000000,%rcx
  4004fe:       40 f7 3f 
  400501:       48 89 4c 24 f8          mov    %rcx,-0x8(%rsp)
  400506:       48 b9 00 00 00 00 00    movabs $0x3ff0000000000000,%rcx
  40050d:       00 f0 3f 
  400510:       48 89 4c 24 f0          mov    %rcx,-0x10(%rsp)
  400515:       85 ff                   test   %edi,%edi
  400517:       48 8d 4c 24 f8          lea    -0x8(%rsp),%rcx
  40051c:       48 8d 54 24 f0          lea    -0x10(%rsp),%rdx
  400521:       48 0f 4f d1             cmovg  %rcx,%rdx
  400525:       48 83 ca 04             or     $0x4,%rdx
  400529:       01 02                   add    %eax,(%rdx)
  40052b:       f2 0f 10 05 b5 00 00    movsd  0xb5(%rip),%xmm0        # 4005e8
<_IO_stdin_used+0x8>
  400532:       00
  400533:       c3                      retq
  400534:       66 66 66 2e 0f 1f 84    data16 data16 nopw %cs:0x0(%rax,%rax,1)
  40053b:       00 00 00 00 00

In other words, it seems to convert the if into something like

  (k > 0 ? &da.L[1] : &db.L[0]) += (k > 0 ? k : -k)

but then basically everything is thrown away at the last instruction,
and it loads the value directly from a constant.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>