[LLVMbugs] [Bug 11234] New: llvm.memory.barrier() : llvm optimization does not respect barrier

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Oct 25 11:29:19 PDT 2011


http://llvm.org/bugs/show_bug.cgi?id=11234

           Summary: llvm.memory.barrier() :  llvm optimization does not
                    respect barrier
           Product: compiler-rt
           Version: unspecified
          Platform: PC
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: compiler-rt
        AssignedTo: unassignedbugs at nondot.org
        ReportedBy: jgu222 at gmail.com
                CC: llvmbugs at cs.uiuc.edu


A memory barrier intrinsic should have two roles:

1.  All compiler optimizations shall respect any memory barrier.

    No optimizations shall be allowed to optimize across any barrier intrinisic

2.  Generate correct machine barrier instructions if needed.

    On some hardware that does memory operation reordering, a memory barrier
instruction should be generated.


Currently,  llvm does not do 1.  Especially,  alias analysis is a
flow-insensitive approach, which does not respect memory 

barrier.  In addition, since the up-coming c++xx standardizes memory/sync
operations, respecting memory barrier is a must.

Here is an example to show the problem:


Issue 1: a barrier with all false arguments prevents optimizations, which it
should not.

// pesudo code
void foo(int *x) {
  x[2] = 10;
  llvm.memory.barrier(0, 0, 0, 0, 0);
  x[2] = 20;
}


The barrier is actually noop,  but it prevents "x[2] = 10" from being deleted.

Issue 2: a barrier with all true arguments is not respected, which is wrong.

// pesudo code
void foo(int * restrict x) {
  x[2] = 10;
  llvm.memory.barrier(1, 1, 1, 1, 1);
  x[2] = 20;
  return void
}

"x[2] = 10' should not be deleted because barrier is present.  But it
is deleted (DCE).


Here is llvm ir for the first case (commented code is for the second case).

declare void @llvm.memory.barrier(i1 , i1 , i1 , i1 , i1)

define void @foo(i32* %x) nounwind {
; define void @foo(i32* noalias %x) nounwind {
entry:
  %x.addr = alloca i32*, align 4
  store i32* %x, i32** %x.addr, align 4
  %tmp = load i32** %x.addr, align 4
  %arrayidx = getelementptr i32* %tmp, i32 2
  store i32 10, i32* %arrayidx, align 4
  call void @llvm.memory.barrier(i1 0, i1 0, i1 0, i1 0, i1 0) nounwind
; call void @llvm.memory.barrier(i1 1, i1 1, i1 1, i1 1, i1 1) nounwind
  %tmp1 = load i32** %x.addr, align 4
  %arrayidx1 = getelementptr i32* %tmp, i32 2
  store i32 20, i32* %arrayidx, align 4
  ret void
}


Using "opt -O3 " and result is

 declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind

define void @foo(i32* nocapture %x) nounwind {
entry:
  %arrayidx = getelementptr i32* %x, i32 2
  store i32 10, i32* %arrayidx, align 4
  tail call void @llvm.memory.barrier(i1 false, i1 false, i1 false, i1
false, i1 false) nounwind
  store i32 20, i32* %arrayidx, align 4
  ret void
}

-- 
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.



More information about the llvm-bugs mailing list