diff --git a/llvm/test/tools/llvm-profgen/Inputs/out-of-bounds.raw.prof b/llvm/test/tools/llvm-profgen/Inputs/out-of-bounds.raw.prof new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-profgen/Inputs/out-of-bounds.raw.prof @@ -0,0 +1,3 @@ +1 +0-ffff:1 +0 diff --git a/llvm/test/tools/llvm-profgen/inline-noprobe.test b/llvm/test/tools/llvm-profgen/inline-noprobe.test --- a/llvm/test/tools/llvm-profgen/inline-noprobe.test +++ b/llvm/test/tools/llvm-profgen/inline-noprobe.test @@ -9,6 +9,8 @@ ; RUN: echo -e "0\n0" > %t ; RUN: llvm-profgen --format=text --unsymbolized-profile=%t --binary=%S/Inputs/inline-noprobe.perfbin --output=%t1 --fill-zero-for-all-funcs ; RUN: FileCheck %s --input-file %t1 --check-prefix=CHECK-ALL-ZERO +; RUN: llvm-profgen --format=text --unsymbolized-profile=%S/Inputs/out-of-bounds.raw.prof --binary=%S/Inputs/inline-noprobe.perfbin --output=%t1 +; RUN: FileCheck %s --input-file %t1 --check-prefix=CHECK-OB CHECK: main:188:0 CHECK: 0: 0 @@ -58,6 +60,33 @@ CHECK-RAW-PROFILE-NEXT: 677->650:21 CHECK-RAW-PROFILE-NEXT: 691->669:43 +;CHECK-OB: foo:8:0 +;CHECK-OB: 0: 1 +;CHECK-OB: 2.1: 1 +;CHECK-OB: 3: 1 +;CHECK-OB: 3.2: 1 +;CHECK-OB: 4: 1 +;CHECK-OB: 3.1: bar:1 +;CHECK-OB: 1: 1 +;CHECK-OB: 3.2: bar:2 +;CHECK-OB: 1: 1 +;CHECK-OB: 7: 1 +;CHECK-OB: main:8:0 +;CHECK-OB: 0: 1 +;CHECK-OB: 2: 1 +;CHECK-OB: 1: foo:6 +;CHECK-OB: 2.1: 1 +;CHECK-OB: 3: 1 +;CHECK-OB: 3.2: 1 +;CHECK-OB: 4: 1 +;CHECK-OB: 3.1: bar:1 +;CHECK-OB: 1: 1 +;CHECK-OB: 3.2: bar:1 +;CHECK-OB: 1: 1 +;CHECK-OB: bar:2:0 +;CHECK-OB: 1: 1 +;CHECK-OB: 5: 1 + ; original code: ; clang -O3 -g -fdebug-info-for-profiling test.c -o a.out #include diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp --- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp +++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp @@ -355,7 +355,7 @@ if (FillZeroForAllFuncs) { for (auto &FuncI : Binary->getAllBinaryFunctions()) { for (auto &R : FuncI.second.Ranges) { - Ranges[{R.first, R.second}] += 0; + Ranges[{R.first, R.second - 1}] += 0; } } } else { @@ -395,7 +395,8 @@ Count); } // Move to next IP within the range. - IP.advance(); + if (!IP.advance()) + break; } } } @@ -547,7 +548,8 @@ } // Move to next IP within the range - IP.advance(); + if (!IP.advance()) + break; } } } @@ -718,9 +720,6 @@ // Disjoint ranges may have range in the middle of two instr, // e.g. If Instr1 at Addr1, and Instr2 at Addr2, disjoint range // can be Addr1+1 to Addr2-1. We should ignore such range. - if (IP.Address > RangeEnd) - continue; - while (IP.Address <= RangeEnd) { const AddressProbesMap &Address2ProbesMap = Binary->getAddress2ProbesMap(); @@ -733,7 +732,8 @@ } } - IP.advance(); + if (!IP.advance()) + break; } } } diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h --- a/llvm/tools/llvm-profgen/ProfiledBinary.h +++ b/llvm/tools/llvm-profgen/ProfiledBinary.h @@ -64,8 +64,8 @@ uint64_t Index = 0; InstructionPointer(const ProfiledBinary *Binary, uint64_t Address, bool RoundToNext = false); - void advance(); - void backward(); + bool advance(); + bool backward(); void update(uint64_t Addr); }; @@ -105,7 +105,8 @@ for (auto I : FuncStartOffsetMap) { PrologEpilogSet.insert(I.first); InstructionPointer IP(Binary, I.first); - IP.advance(); + if (!IP.advance()) + break; PrologEpilogSet.insert(IP.Offset); } } @@ -115,7 +116,8 @@ for (auto Addr : RetAddrs) { PrologEpilogSet.insert(Addr); InstructionPointer IP(Binary, Addr); - IP.backward(); + if (!IP.backward()) + break; PrologEpilogSet.insert(IP.Offset); } } @@ -336,6 +338,8 @@ return offsetToVirtualAddr(CodeAddrOffsets[Index]); } + size_t getCodeOffsetsSize() const { return CodeAddrOffsets.size(); } + bool usePseudoProbes() const { return UsePseudoProbes; } // Get the index in CodeAddrOffsets for the address // As we might get an address which is not the code diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -686,14 +686,24 @@ } } -void InstructionPointer::advance() { +bool InstructionPointer::advance() { Index++; + if (Index >= Binary->getCodeOffsetsSize()) { + Address = UINT64_MAX; + return false; + } Address = Binary->getAddressforIndex(Index); + return true; } -void InstructionPointer::backward() { +bool InstructionPointer::backward() { + if (Index == 0) { + Address = 0; + return false; + } Index--; Address = Binary->getAddressforIndex(Index); + return true; } void InstructionPointer::update(uint64_t Addr) {