[LLVMdev] llvm.memory.barrier does not work

Junjie Gu jgu222 at gmail.com
Wed Sep 28 15:27:18 PDT 2011


Instrinsic llvm.memory.barrier does not work as expected.  Is it a bug
or it has not been implemented yet ?

(1) false arguments do not work

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


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

(2) True arguments do not work.

// 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 anyway.


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
}



More information about the llvm-dev mailing list