[LLVMdev] A question w.r.t fence instruction vs. noalias pointer

Guo, Xiaoyi Xiaoyi.Guo at amd.com
Wed Jun 12 18:17:43 PDT 2013


Hi,

I have the following test case:

define  void @foo(<2 x float>* noalias nocapture %out, <2 x float>* noalias nocapture %data0) nounwind {
entry:
  %val1 = load <2 x float>* %data0, align 8
  store <2 x float> %val1, <2 x float>* %out, align 8
  fence acq_rel
  %val2 = load <2 x float>* %data0, align 8
  store <2 x float> %val2, <2 x float>* %out, align 8
  ret void
}

If I run it though GVN with BasicAliasAnalysis, GVN does not remove the load after the fence.

However, if I put the fence instruction in a function, such as:

define  void @foo(<2 x float>* noalias nocapture %out, <2 x float>* noalias nocapture %data0) nounwind {
entry:
  %val1 = load <2 x float>* %data0, align 8
  store <2 x float> %val1, <2 x float>* %out, align 8
  tail call void @barrier(i32 0, i32 1) nounwind
  %val2 = load <2 x float>* %data0, align 8
  store <2 x float> %val2, <2 x float>* %out, align 8
  ret void
}

define  void @barrier(i32, i32) nounwind {
  fence acq_rel
  ret void
}

Then GVN would remove the load after the barrier() call.

I'm not very sure whether this is the correct behavior. In other words, should a fence instruction be able to prevent noalias pointers in the caller function from being reordered? If not, then if the barrier() function is later being inlined, then the fence instruction would be able to prevent the loads from being moved across it, as in the first example. But then we would get different behavior depending on whether the function is inlined or not.

I would appreciate it if someone could clarify this for me.

Thanks,
Xiaoyi





More information about the llvm-dev mailing list