[llvm-bugs] [Bug 33278] New: Loses aliasing information through union when rewriting into conditional move

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Jun 2 06:38:44 PDT 2017


https://bugs.llvm.org/show_bug.cgi?id=33278

            Bug ID: 33278
           Summary: Loses aliasing information through union when
                    rewriting into conditional move
           Product: new-bugs
           Version: 4.0
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: new bugs
          Assignee: unassignedbugs at nondot.org
          Reporter: steinar+llvm at gunderson.no
                CC: llvm-bugs at lists.llvm.org

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.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170602/ae2331e1/attachment.html>


More information about the llvm-bugs mailing list