diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h --- a/llvm/tools/llvm-profgen/PerfReader.h +++ b/llvm/tools/llvm-profgen/PerfReader.h @@ -217,6 +217,14 @@ using SampleVector = SmallVector, 16>; + +inline bool isValidLBRRange(uint64_t Start, uint64_t End) +{ + // Start bigger than End is considered invalid. + // Larger LBR ranges are also assumed invalid. + return Start <= End && End <= Start + (1 << 20); +} + // The state for the unwinder, it doesn't hold the data but only keep the // pointer/index of the data, While unwinding, the CallStack is changed // dynamicially and will be recorded as the context of the sample diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp --- a/llvm/tools/llvm-profgen/PerfReader.cpp +++ b/llvm/tools/llvm-profgen/PerfReader.cpp @@ -100,7 +100,7 @@ InstructionPointer &IP = State.InstPtr; uint64_t Target = State.getCurrentLBRTarget(); uint64_t End = IP.Address; - if (Target > End) { + if (!isValidLBRRange(Target, End)) { // Skip unwinding the rest of LBR trace when a bogus range is seen. State.setInvalid(); return; @@ -932,7 +932,7 @@ // LBR and FROM of next LBR. uint64_t StartOffset = TargetOffset; if (EndOffeset != 0) { - if (StartOffset <= EndOffeset) + if (isValidLBRRange(StartOffset, EndOffeset)) Counter.recordRangeCount(StartOffset, EndOffeset, Repeat); } EndOffeset = SourceOffset; @@ -1179,7 +1179,7 @@ const char *RangeCrossFuncMsg = "Fall through range should not cross function boundaries, likely due to " "profile and binary mismatch."; - const char *BogusRangeMsg = "Range start is after range end."; + const char *BogusRangeMsg = "Range start is after or too far from range end."; uint64_t TotalRangeNum = 0; uint64_t InstNotBoundary = 0; @@ -1210,7 +1210,7 @@ WarnInvalidRange(StartOffset, EndOffset, RangeCrossFuncMsg); } - if (StartOffset > EndOffset) { + if (!isValidLBRRange(StartOffset, EndOffset)) { BogusRange += I.second; WarnInvalidRange(StartOffset, EndOffset, BogusRangeMsg); } @@ -1225,9 +1225,9 @@ emitWarningSummary( RangeCrossFunc, TotalRangeNum, "of samples are from ranges that do cross function boundaries."); - emitWarningSummary( - BogusRange, TotalRangeNum, - "of samples are from ranges that have range start after range end."); + emitWarningSummary(BogusRange, TotalRangeNum, + "of samples are from ranges that have range start after " + "or too far from range end."); } void PerfScriptReader::parsePerfTraces() {