diff --git a/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h index 4b7fb6f9400..4d12df903da 100644 --- a/include/llvm/ProfileData/InstrProf.h +++ b/include/llvm/ProfileData/InstrProf.h @@ -292,7 +292,8 @@ enum class instrprof_error { counter_overflow, value_site_count_mismatch, compress_failed, - uncompress_failed + uncompress_failed, + empty_raw_profile }; inline std::error_code make_error_code(instrprof_error E) { diff --git a/lib/ProfileData/InstrProf.cpp b/lib/ProfileData/InstrProf.cpp index dac91950183..b512f543e95 100644 --- a/lib/ProfileData/InstrProf.cpp +++ b/lib/ProfileData/InstrProf.cpp @@ -70,6 +70,8 @@ std::string getInstrProfErrString(instrprof_error Err) { return "Failed to compress data (zlib)"; case instrprof_error::uncompress_failed: return "Failed to uncompress data (zlib)"; + case instrprof_error::empty_raw_profile: + return "Empty raw profile file"; } llvm_unreachable("A value of instrprof_error has no message."); } diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index 81c13b35ce3..ed927a98604 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/lib/ProfileData/InstrProfReader.cpp @@ -46,6 +46,9 @@ InstrProfReader::create(std::unique_ptr Buffer) { if (Buffer->getBufferSize() > std::numeric_limits::max()) return make_error(instrprof_error::too_large); + if (Buffer->getBufferSize() == 0) + return make_error(instrprof_error::empty_raw_profile); + std::unique_ptr Result; // Create the reader. if (IndexedInstrProfReader::hasFormat(*Buffer)) diff --git a/test/tools/llvm-profdata/Inputs/IR_profile.proftext b/test/tools/llvm-profdata/Inputs/IR_profile.proftext new file mode 100644 index 00000000000..7b7340ec295 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/IR_profile.proftext @@ -0,0 +1,9 @@ +:ir +main +# Func Hash: +12884901887 +# Num Counters: +1 +# Counter Values: +1 + diff --git a/test/tools/llvm-profdata/Inputs/clang_profile.proftext b/test/tools/llvm-profdata/Inputs/clang_profile.proftext new file mode 100644 index 00000000000..5419d233fc0 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/clang_profile.proftext @@ -0,0 +1,8 @@ +main +# Func Hash: +0 +# Num Counters: +1 +# Counter Values: +1 + diff --git a/test/tools/llvm-profdata/merge_empty_profile.test b/test/tools/llvm-profdata/merge_empty_profile.test new file mode 100644 index 00000000000..7f9d31bd8f5 --- /dev/null +++ b/test/tools/llvm-profdata/merge_empty_profile.test @@ -0,0 +1,17 @@ +# Tests for merge of empty profile files. + +RUN: touch %t_empty.proftext +RUN: llvm-profdata merge -text -o %t_clang.proftext %t_empty.proftext %p/Inputs/clang_profile.proftext +RUN: FileCheck --input-file=%t_clang.proftext %s -check-prefix=CLANG_PROF_TEXT +CLANG_PROF_TEXT: main +CLANG_PROF_TEXT: 0 +CLANG_PROF_TEXT: 1 +CLANG_PROF_TEXT: 1 + +RUN: llvm-profdata merge -text -o %t_ir.proftext %t_empty.proftext %p/Inputs/IR_profile.proftext +RUN: FileCheck --input-file=%t_ir.proftext %s -check-prefix=IR_PROF_TEXT +IR_PROF_TEXT: :ir +IR_PROF_TEXT: main +IR_PROF_TEXT: 0 +IR_PROF_TEXT: 1 +IR_PROF_TEXT: 1 diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp index 08f74d955c6..b9e30255ae3 100644 --- a/tools/llvm-profdata/llvm-profdata.cpp +++ b/tools/llvm-profdata/llvm-profdata.cpp @@ -140,8 +140,13 @@ static void loadInput(const WeightedFile &Input, WriterContext *WC) { WC->ErrWhence = Input.Filename; auto ReaderOrErr = InstrProfReader::create(Input.Filename); - if ((WC->Err = ReaderOrErr.takeError())) + if (Error E = ReaderOrErr.takeError()) { + // Skip the empty profiles by returning sliently. + instrprof_error IPE = InstrProfError::take(std::move(E)); + if (IPE != instrprof_error::empty_raw_profile) + WC->Err = make_error(IPE); return; + } auto Reader = std::move(ReaderOrErr.get()); bool IsIRProfile = Reader->isIRLevelProfile();