<html>
    <head>
      <base href="http://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 --- - IR Generation Introduces an Incorrect Volatile, Preventing Optimization"
   href="http://llvm.org/bugs/show_bug.cgi?id=17306">17306</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>IR Generation Introduces an Incorrect Volatile, Preventing Optimization
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

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

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Keywords</th>
          <td>code-quality
          </td>
        </tr>

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

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

        <tr>
          <th>Component</th>
          <td>LLVM Codegen
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>whunt@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>When implementing some intrinsics I have come across an IR-gen bug that is
causing clang to produce very bad code around.  After looking at it for a bit,
I've narrowed it down to a load that's incorrectly marked as volatile.  If that
the volatile is removed by hand and the result compiled, the optimizer
generates the correct code.

//------------------------------------------------------------------------------
// C++ code
//------------------------------------------------------------------------------

#ifdef __clang__
static __inline__ long __attribute__((__always_inline__, __nodebug__))
_InterlockedExchangeAdd(volatile long* _Addend, long _Value) {
  return __atomic_add_fetch(_Addend, _Value, 0) - _Value;
}
#else
#include <intrin.h>
#endif

__declspec(noinline) long test(volatile long* p, long a) {
  return _InterlockedExchangeAdd(p, a);
}

extern "C" void printf(const char*, ...);

int main() {
  volatile long i = 1;
  long a = test(&i, 0xf);
  printf("%d, %d\n", i, a);
}

//------------------------------------------------------------------------------
// LLVM IR code
//------------------------------------------------------------------------------

define i32 @"\01?test@@YAJPCJJ@Z"(i32* %p, i32 %a) #0 {
entry:
  %.atomicdst.i = alloca i32, align 4
  %.atomicdst.i.0.cast = bitcast i32* %.atomicdst.i to i8*
  call void @llvm.lifetime.start(i64 4, i8* %.atomicdst.i.0.cast)
  %0 = atomicrmw volatile add i32* %p, i32 %a monotonic
  %1 = add i32 %0, %a
  store i32 %1, i32* %.atomicdst.i, align 4
  %.atomicdst.i.0.load = load volatile i32* %.atomicdst.i, align 4
  %sub.i = sub nsw i32 %.atomicdst.i.0.load, %a
  call void @llvm.lifetime.end(i64 4, i8* %.atomicdst.i.0.cast)
  ret i32 %sub.i
}

//------------------------------------------------------------------------------
// Bug!! From IR code:
//------------------------------------------------------------------------------

%.atomicdst.i.0.load = load volatile i32* %.atomicdst.i, align 4
Should *not* be marked volatile.

//------------------------------------------------------------------------------
// Incorrect ASM (current)
//------------------------------------------------------------------------------

00091002 E5 50                in          eax,50h  
00091004 8B 45 08             mov         eax,dword ptr [ebp+8]  
00091007 8B 4D 0C             mov         ecx,dword ptr [ebp+0Ch]  
0009100A 89 CA                mov         edx,ecx  
0009100C F0 0F C1 10          lock xadd   dword ptr [eax],edx  
00091010 01 CA                add         edx,ecx  
00091012 89 55 FC             mov         dword ptr [ebp-4],edx  
00091015 8B 45 FC             mov         eax,dword ptr [ebp-4]  
00091018 29 C8                sub         eax,ecx  
0009101A 83 C4 04             add         esp,4  
0009101D 5D                   pop         ebp  
0009101E C3                   ret  

//------------------------------------------------------------------------------
// Correct ASM (correctly generated if volatile is removed)
//------------------------------------------------------------------------------

009F1005 F0 0F C1 01          lock xadd   dword ptr [ecx],eax  
012A1009 C3                   ret</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>