diff --git a/compiler-rt/lib/profile/InstrProfilingFile.c b/compiler-rt/lib/profile/InstrProfilingFile.c --- a/compiler-rt/lib/profile/InstrProfilingFile.c +++ b/compiler-rt/lib/profile/InstrProfilingFile.c @@ -588,12 +588,22 @@ lprofCurFilename.PNS = PNS_default; } -static int containsMergeSpecifier(const char *FilenamePat, int I) { - return (FilenamePat[I] == 'm' || - (FilenamePat[I] >= '1' && FilenamePat[I] <= '9' && - /* If FilenamePat[I] is not '\0', the next byte is guaranteed - * to be in-bound as the string is null terminated. */ - FilenamePat[I + 1] == 'm')); +static unsigned getMergePoolSize(const char *FilenamePat, int *I) { + unsigned J = 0, Num = 0; + for (;; ++J) { + char C = FilenamePat[*I + J]; + if (C == 'm') { + *I += J; + return Num ? Num : 1; + } + if (C < '0' || C > '9') + break; + Num = Num * 10 + C - '0'; + + /* If FilenamePat[*I+J] is between '0' and '9', the next byte is guaranteed + * to be in-bound as the string is null terminated. */ + } + return 0; } /* Parses the pattern string \p FilenamePat and stores the result to @@ -650,19 +660,17 @@ __llvm_profile_enable_continuous_mode(); I++; /* advance to 'c' */ - } else if (containsMergeSpecifier(FilenamePat, I)) { + } else { + unsigned MergePoolSize = getMergePoolSize(FilenamePat, &I); + if (!MergePoolSize) + continue; if (MergingEnabled) { PROF_WARN("%%m specifier can only be specified once in %s.\n", FilenamePat); return -1; } MergingEnabled = 1; - if (FilenamePat[I] == 'm') - lprofCurFilename.MergePoolSize = 1; - else { - lprofCurFilename.MergePoolSize = FilenamePat[I] - '0'; - I++; /* advance to 'm' */ - } + lprofCurFilename.MergePoolSize = MergePoolSize; } } @@ -766,7 +774,9 @@ } else if (FilenamePat[I] == 'h') { memcpy(FilenameBuf + J, lprofCurFilename.Hostname, HostNameLength); J += HostNameLength; - } else if (containsMergeSpecifier(FilenamePat, I)) { + } else { + if (!getMergePoolSize(FilenamePat, &I)) + continue; char LoadModuleSignature[SIGLEN]; int S; int ProfilePoolId = getpid() % lprofCurFilename.MergePoolSize; @@ -776,8 +786,6 @@ S = SIGLEN; memcpy(FilenameBuf + J, LoadModuleSignature, S); J += S; - if (FilenamePat[I] != 'm') - I++; } /* Drop any unknown substitutions. */ } else diff --git a/compiler-rt/test/profile/instrprof-basic.c b/compiler-rt/test/profile/instrprof-basic.c --- a/compiler-rt/test/profile/instrprof-basic.c +++ b/compiler-rt/test/profile/instrprof-basic.c @@ -42,6 +42,13 @@ // RUN: llvm-profdata merge -o %t.m4.profdata ./ // RUN: %clang_profuse=%t.m4.profdata -O0 -o - -S -emit-llvm %s | FileCheck %s --check-prefix=COMMON --check-prefix=PGOMERGE +/// Test that the merge pool size can be larger than 10. +// RUN: rm -fr %t.dir5 +// RUN: mkdir -p %t.dir5 +// RUN: env LLVM_PROFILE_FILE=%t.dir5/profraw_e_%20m %run %t +// RUN: not ls %t.dir5/profraw_e_%20m +// RUN: ls %t.dir5/profraw_e_* | count 1 + int begin(int i) { // COMMON: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] if (i)