diff --git a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp index 1872f550c3f31..c1660c2d4a1b8 100644 --- a/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp +++ b/llvm/tools/llvm-exegesis/lib/SnippetRepetitor.cpp @@ -30,10 +30,10 @@ class DuplicateSnippetRepetitor : public SnippetRepetitor { CleanupMemory](FunctionFiller &Filler) { auto Entry = Filler.getEntry(); if (!Instructions.empty()) { - // Add the whole snippet at least once. - Entry.addInstructions(Instructions); - for (unsigned I = Instructions.size(); I < MinInstructions; ++I) { - Entry.addInstruction(Instructions[I % Instructions.size()]); + const unsigned NumRepetitions = + divideCeil(MinInstructions, Instructions.size()); + for (unsigned I = 0; I < NumRepetitions; ++I) { + Entry.addInstructions(Instructions); } } Entry.addReturn(State.getExegesisTarget(), CleanupMemory); diff --git a/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp b/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp index d2382ec0cddc4..25e8836087c15 100644 --- a/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp +++ b/llvm/unittests/tools/llvm-exegesis/X86/SnippetRepetitorTest.cpp @@ -38,9 +38,11 @@ class X86SnippetRepetitorTest : public X86TestBase { MF = &createVoidVoidPtrMachineFunction("TestFn", Mod.get(), MMI.get()); } - void TestCommon(Benchmark::RepetitionModeE RepetitionMode) { + void TestCommon(Benchmark::RepetitionModeE RepetitionMode, + unsigned SnippetInstructions = 1) { const auto Repetitor = SnippetRepetitor::Create(RepetitionMode, State); - const std::vector Instructions = {MCInstBuilder(X86::NOOP)}; + const std::vector Instructions(SnippetInstructions, + MCInstBuilder(X86::NOOP)); FunctionFiller Sink(*MF, {X86::EAX}); const auto Fill = Repetitor->Repeat(Instructions, kMinInstructions, kLoopBodySize, false); @@ -74,6 +76,18 @@ TEST_F(X86SnippetRepetitorTest, Duplicate) { HasOpcode(X86::NOOP), HasOpcode(X86::RET64))); } +TEST_F(X86SnippetRepetitorTest, DuplicateSnippetInstructionCount) { + TestCommon(Benchmark::Duplicate, 2); + // Duplicating a snippet of two instructions with the minimum number of + // instructions set to three duplicates the snippet twice for a total of + // four instructions. + ASSERT_EQ(MF->getNumBlockIDs(), 1u); + EXPECT_THAT(MF->getBlockNumbered(0)->instrs(), + ElementsAre(HasOpcode(X86::NOOP), HasOpcode(X86::NOOP), + HasOpcode(X86::NOOP), HasOpcode(X86::NOOP), + HasOpcode(X86::RET64))); +} + TEST_F(X86SnippetRepetitorTest, Loop) { TestCommon(Benchmark::Loop); // Duplicating creates an entry block, a loop body and a ret block.