http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56360



             Bug #: 56360

           Summary: Loop invariant motion can introduce speculative store

    Classification: Unclassified

           Product: gcc

           Version: 4.8.0

            Status: UNCONFIRMED

          Keywords: wrong-code

          Severity: normal

          Priority: P3

         Component: tree-optimization

        AssignedTo: unassig...@gcc.gnu.org

        ReportedBy: i...@airs.com





When I compile this C++ program with -O3 -std=gnu+11 on x86_64:



#include<mutex>

#include<thread>



extern int a;

std::mutex m;



void nop2(int*);



// this function is ONLY called with i=0.

void foo(int i)

{

  if (i) m.lock();

  nop2(&i); // Only here to prevent optimiser from creating one big if().

  for (int c = 0; c < 10000; ++c) {

    if (i) {

      ++a; // Thus this is never executed.

    }

  }

  nop2(&i); // Only here to prevent optimiser from creating one big if().

  if (i) m.unlock();

}



I see this in _Z3fooi:



        movl    a(%rip), %eax

        movl    12(%rsp), %ecx

        leaq    12(%rsp), %rdi

        leal    10000(%rax), %edx

        testl   %ecx, %ecx

        cmovne  %edx, %eax

        movl    %eax, a(%rip)



This unconditionally stores a value in a.  This is a speculative store, which

is invalid according to the C++ memory model.



This does not happen with -O2.



>From looking at the dumps, the bug appears to be in the loop invariant motion

pass.

Reply via email to