[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