From 6a23d2764467bd45c2e02828f6175a0b9f9a1005 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 16 Mar 2022 16:10:24 +0100 Subject: [PATCH] [FuzzMutate] Don't insert instructions after musttail call --- llvm/lib/FuzzMutate/IRMutator.cpp | 10 ++++++++++ llvm/unittests/FuzzMutate/StrategiesTest.cpp | 30 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/llvm/lib/FuzzMutate/IRMutator.cpp b/llvm/lib/FuzzMutate/IRMutator.cpp index 105f8bc..0f93bf9 100644 --- a/llvm/lib/FuzzMutate/IRMutator.cpp +++ b/llvm/lib/FuzzMutate/IRMutator.cpp @@ -116,6 +116,16 @@ void InjectorIRStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) { auto InstsBefore = makeArrayRef(Insts).slice(0, IP); auto InstsAfter = makeArrayRef(Insts).slice(IP); + if (!InstsBefore.empty()) { + // Don't insert instructions after a musttail call. + Instruction *InstBefore = InstsBefore.back(); + if (isa(InstBefore)) + InstBefore = InstBefore->getPrevNode(); + CallBase *CallBefore = dyn_cast_or_null(InstBefore); + if (CallBefore && CallBefore->isMustTailCall()) + return; + } + // Choose a source, which will be used to constrain the operation selection. SmallVector Srcs; Srcs.push_back(IB.findOrCreateSource(BB, InstsBefore)); diff --git a/llvm/unittests/FuzzMutate/StrategiesTest.cpp b/llvm/unittests/FuzzMutate/StrategiesTest.cpp index 562d08b..9954a63 100644 --- a/llvm/unittests/FuzzMutate/StrategiesTest.cpp +++ b/llvm/unittests/FuzzMutate/StrategiesTest.cpp @@ -100,6 +100,36 @@ TEST(InjectorIRStrategyTest, EmptyModule) { EXPECT_TRUE(!verifyModule(*M, &errs())); } +TEST(InjectorIRStrategyTest, MustTailCall) { + // Test that we don't insert after a musttail call. + StringRef Source = "" + "define i32 @func() {\n" + "%v = musttail call i32 @func()\n" + "ret i32 %v\n" + "}\n"; + + auto Mutator = createInjectorMutator(); + ASSERT_TRUE(Mutator); + + IterateOnSource(Source, *Mutator); +} + +TEST(InjectorIRStrategyTest, MustTailCallBitCast) { + // Test that we don't insert after a musttail call bitcast. + StringRef Source = "" + "declare i32* @func2()\n" + "define i8* @func() {\n" + "%v = musttail call i32* @func2()\n" + "%v2 = bitcast i32* %v to i8*\n" + "ret i8* %v2\n" + "}\n"; + + auto Mutator = createInjectorMutator(); + ASSERT_TRUE(Mutator); + + IterateOnSource(Source, *Mutator); +} + TEST(InstDeleterIRStrategyTest, EmptyFunction) { // Test that we don't crash even if we can't remove from one of the functions. -- 2.7.4