[PATCH] Fixing a heisenbug where the memory dependence analysis behaves differently with and without -g
David Blaikie
dblaikie at gmail.com
Mon Nov 11 19:37:46 PST 2013
Idea looks sound - could use a commitable test case, though.
On Mon, Nov 11, 2013 at 7:36 PM, Yunzhong Gao <
Yunzhong_Gao at playstation.sony.com> wrote:
> 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 --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131111/757010d5/attachment.html>
More information about the llvm-commits
mailing list