From 51a1e3c4309002056181409f166ef8fd147a9644 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Tue, 13 Dec 2016 06:41:14 +0000 Subject: [PATCH] [PGO] Fix insane counts due to nonreturn calls Summary: Since we don't break BBs for function calls. We might get some insane counts (wrap of unsigned) in the presence of noreturn calls. This patch sets these counts to zero instead of the wrapped number. Reviewers: davidxl Subscribers: xur, eraman, llvm-commits Differential Revision: https://reviews.llvm.org/D27602 llvm-svn: 289521 --- .../Instrumentation/PGOInstrumentation.cpp | 13 +++++- .../PGOProfile/Inputs/noreturncall.proftext | 11 ++++++ llvm/test/Transforms/PGOProfile/noreturncall.ll | 46 ++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/PGOProfile/Inputs/noreturncall.proftext create mode 100644 llvm/test/Transforms/PGOProfile/noreturncall.ll diff --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp index d802295..28f4f7e 100644 --- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -884,12 +884,21 @@ void PGOUseFunc::populateCounters() { } if (Count->CountValid) { if (Count->UnknownCountOutEdge == 1) { - uint64_t Total = Count->CountValue - sumEdgeCount(Count->OutEdges); + uint64_t Total = 0; + uint64_t OutSum = sumEdgeCount(Count->OutEdges); + // If the one of the successor block can early terminate (no-return), + // we can end up with situation where out edge sum count is larger as + // the source BB's count is collected by a post-dominated block. + if (Count->CountValue > OutSum) + Total = Count->CountValue - OutSum; setEdgeCount(Count->OutEdges, Total); Changes = true; } if (Count->UnknownCountInEdge == 1) { - uint64_t Total = Count->CountValue - sumEdgeCount(Count->InEdges); + uint64_t Total = 0; + uint64_t InSum = sumEdgeCount(Count->InEdges); + if (Count->CountValue > InSum) + Total = Count->CountValue - InSum; setEdgeCount(Count->InEdges, Total); Changes = true; } diff --git a/llvm/test/Transforms/PGOProfile/Inputs/noreturncall.proftext b/llvm/test/Transforms/PGOProfile/Inputs/noreturncall.proftext new file mode 100644 index 0000000..73ee83f --- /dev/null +++ b/llvm/test/Transforms/PGOProfile/Inputs/noreturncall.proftext @@ -0,0 +1,11 @@ +# IR level Instrumentation Flag +:ir +foo +# Func Hash: +36496524737 +# Num Counters: +3 +# Counter Values: +20 +21 +0 diff --git a/llvm/test/Transforms/PGOProfile/noreturncall.ll b/llvm/test/Transforms/PGOProfile/noreturncall.ll new file mode 100644 index 0000000..602ebeb --- /dev/null +++ b/llvm/test/Transforms/PGOProfile/noreturncall.ll @@ -0,0 +1,46 @@ +; RUN: llvm-profdata merge %S/Inputs/noreturncall.proftext -o %t.profdata +; RUN: opt < %s -pgo-instr-use -pgo-test-profile-file=%t.profdata -S -debug-only=pgo-instrumentation 2>&1 | FileCheck %s --check-prefix=USE +; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -S -debug-only=pgo-instrumentation 2>&1 | FileCheck %s --check-prefix=USE + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +declare i32 @bar0(i32) + +define i32 @bar2(i32 %i) { +entry: + unreachable +} + +define i32 @foo(i32 %i, i32 %j, i32 %k) { +entry: + %cmp = icmp slt i32 %i, 999 + br i1 %cmp, label %if.then, label %if.end + +if.then: + %call = call i32 @bar0(i32 %i) + br label %if.end + +if.end: + %ret.0 = phi i32 [ %call, %if.then ], [ 0, %entry ] + %cmp1 = icmp sgt i32 %j, 1000 + %cmp3 = icmp sgt i32 %k, 99 + %or.cond = and i1 %cmp1, %cmp3 + br i1 %or.cond, label %if.then4, label %if.end7 + +if.then4: + %call5 = call i32 @bar2(i32 undef) + br label %if.end7 + +if.end7: + %mul = mul nsw i32 %ret.0, %ret.0 + ret i32 %mul +} +; USE: Edge 0: 1-->3 c W=8000 Count=0 +; USE: Edge 1: 3-->5 c W=8000 Count=20 +; USE: Edge 2: 0-->1 W=16 Count=21 +; USE: Edge 3: 5-->0 * W=16 Count=20 +; USE: Edge 4: 1-->2 W=8 Count=21 +; USE: Edge 5: 2-->3 * W=8 Count=21 +; USE: Edge 6: 3-->4 W=8 Count=0 +; USE: Edge 7: 4-->5 * W=8 Count=0 -- 2.7.4