[PATCH] Fixing a heisenbug where the memory dependence analysis behaves differently with and without -g
Yunzhong Gao
Yunzhong_Gao at playstation.sony.com
Mon Nov 11 19:36:22 PST 2013
ygao added you to the CC list for the revision "Fixing a heisenbug where the memory dependence analysis behaves differently with and without -g".
Hi,
I was debugging the following cpp file and I noticed that the memory dependence analysis returns
different results depending on whether the LLVM IR file contains debug metadata. I traced it down
to a place in the memory dependence analysis pass where the debug intrinsics are counted into
the permitted number of instructions to be scanned before bailing out.
Here is the test case:
```
/* test.cpp
*
* To reproduce:
* (1) compile with -g (test.cpp => O1g.ll => O1g_o.ll => O1g.s)
* $ clang++ -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm \
* -mrelocation-model static -target-cpu x86-64 -std=gnu++0x -O1 -g \
* -o O1g.ll -x c++ test.cpp
* $ opt -tbaa -basicaa -inline -sroa -early-cse -simplifycfg -loop-unroll \
* -gvn -instcombine -dse O1g.ll -S -o O1g_o.ll
* $ llc -march=x86-64 -mtriple=x86_64-unknown-linux-gnu \
* -relocation-model=static -filetype=asm O1g_o.ll -o O1g.s
*
* (2) compile without -g (test.cpp => O1.ll => O1_o.ll => O1.s)
* $ clang++ -cc1 -triple x86_64-unknown-linux-gnu -emit-llvm \
* -mrelocation-model static -target-cpu x86-64 -std=gnu++0x -O1 \
* -o O1.ll -x c++ test.cpp
* $ opt -tbaa -basicaa -inline -sroa -early-cse -simplifycfg -loop-unroll \
* -gvn -instcombine -dse O1.ll -S -o O1_o.ll
* $ llc -march=x86-64 -mtriple=x86_64-unknown-linux-gnu \
* -relocation-model=static -filetype=asm O1_o.ll -o O1.s
*
* (3) compare the outputs O1g.s and O1.s; they have different instructions.
*
*/
typedef unsigned long size_t;
inline void *operator new(size_t, void *where) { return where; }
struct int_array
{
int_array(int *input, size_t count)
{
data = (int *) ::operator new(count * sizeof(int));
for (size_t idx = 0; idx < count; ++idx, ++input)
::new (&data[idx]) int(static_cast<int&&>(*input));
}
~int_array() noexcept { delete data; data = 0; }
int& operator[](size_t idx) { return data[idx]; }
private:
int *data;
};
int main()
{
int a1[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
int a2[5] = {-1, -2, -3, -4, -5};
int_array v1(a1, 16);
int_array v2(a2, 5);
v1[1] = -1;
v1[4] = -2;
v1[7] = -3;
v1[10] = -4;
v1[13] = -5;
return 0;
}
/* end of test.cpp */
```
The patch is fairly straight-forward in itself, although I am seeking some advice on how to
write a regression test for this bug. Or should I just submit the patch without a test case?
- Gao.
http://llvm-reviews.chandlerc.com/D2141
Files:
llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
Index: llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
===================================================================
--- llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
+++ llvm/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -371,18 +371,19 @@
// Walk backwards through the basic block, looking for dependencies.
while (ScanIt != BB->begin()) {
+ Instruction *Inst = --ScanIt;
+
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst))
+ // Debug intrinsics don't (and can't) cause dependences.
+ if (isa<DbgInfoIntrinsic>(II)) continue;
+
// Limit the amount of scanning we do so we don't end up with quadratic
// running time on extreme testcases.
--Limit;
if (!Limit)
return MemDepResult::getUnknown();
- Instruction *Inst = --ScanIt;
-
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
- // Debug intrinsics don't (and can't) cause dependences.
- if (isa<DbgInfoIntrinsic>(II)) continue;
-
// If we reach a lifetime begin or end marker, then the query ends here
// because the value is undefined.
if (II->getIntrinsicID() == Intrinsic::lifetime_start) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2141.1.patch
Type: text/x-patch
Size: 1159 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131111/4ccb07cd/attachment.bin>
More information about the llvm-commits
mailing list