<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Bit shifting __int128 return wrong result"
   href="https://llvm.org/bugs/show_bug.cgi?id=25985">25985</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Bit shifting __int128 return wrong result
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>3.7
          </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>Backend: AArch64
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>yyc1992@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Bit shifting a `__int128` constant by (a `int64_t` variable which is) zero
returns wrong result. This is causing a test failure in julia on AArch64.

The c repro for Clang 3.7 is (including a printing that makes it easier to run)

```
#include <stdint.h>
#include <stdio.h>

__attribute__((noinline)) void f(__int128 *p, uint64_t i)
{
    /* *p = i > 127 ? 0 : ((__int128)0xffff) << i; */
    *p = ((__int128)0xffff) << i;
}

int main()
{
    union {
        struct {
            int64_t lo;
            int64_t hi;
        };
        __int128 i128;
    } v;
    f(&v.i128, 0);
    printf("%ld, %ld\n", v.lo, v.hi);
    return 0;
}
```

When compiled with clang, this print out `65535, 65535` and when compiling with
gcc this print out `65535, 0` (<-- correct result).

ASM produced by clang (-O2)

```
f:                                      // @f
// BB#0:
        sub     x8, x1, #64             // =64
        orr     w9, wzr, #0xffff
        orr     w10, wzr, #0x40
        lsl     x11, x9, x8
        sub      x10, x10, x1
        cmp      x8, #0                 // =0
        lsl     x8, x9, x1
        lsr     x9, x9, x10
        csel    x8, xzr, x8, ge
        csel    x9, x11, x9, ge
        stp      x8, x9, [x0]
        ret
```

ASM produced by gcc (-O2)

```
f:
        mvn     w4, w1
        mov     x2, 65535
        mov     x3, 32767
        lsl     x2, x2, x1
        lsr     x3, x3, x4
        ands    w1, w1, 64
        csel    x3, x3, x2, eq
        cmp     w1, wzr
        csel    x2, x2, xzr, eq
        stp     x2, x3, [x0]
        ret
```

LLVM IR produced by clang (-O2), which looks fine AFAICT.

```
define void @f(i128* nocapture %p, i64 %i) #0 {
  %1 = zext i64 %i to i128
  %2 = shl i128 65535, %1
  store i128 %2, i128* %p, align 16, !tbaa !1
  ret void
}
```</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>