Index: llvm/test/tools/llvm-reduce/reduce-function-personality.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/reduce-function-personality.ll @@ -0,0 +1,58 @@ +; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=function-data --test FileCheck --test-arg --check-prefixes=CHECK,INTERESTING --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck -check-prefixes=CHECK,RESULT %s < %t + +; INTERESTING: define void @drop_personality( +; RESULT: define void @drop_personality() { +define void @drop_personality() personality ptr @__gxx_personality_v0 { + ret void +} + +; CHECK: define void @keep_personality() personality ptr @__gxx_personality_v0 { +define void @keep_personality() personality ptr @__gxx_personality_v0 { + ret void +} + +; Make sure an invalid reduction isn't produced if we need a +; personality function for different instructions + +; CHECK: define void @landingpad_requires_personality() +; RESULT-SAME: personality ptr @__gxx_personality_v0 { +define void @landingpad_requires_personality() personality ptr @__gxx_personality_v0 { +bb0: + br label %bb2 + +bb1: + landingpad { ptr, i32 } + catch ptr null + ret void + +bb2: + ret void +} + +; CHECK-LABEL: define void @uses_catchpad() +; RESULT-SAME: personality ptr @__CxxFrameHandler3 { +define void @uses_catchpad() personality ptr @__CxxFrameHandler3 { +entry: + br label %unreachable + +catch.dispatch: + %cs = catchswitch within none [label %catch] unwind to caller + +catch: + %cp = catchpad within %cs [ptr null, i32 64, ptr null] + br label %unreachable + +unreachable: + unreachable +} + +; CHECK-LABEL: define void @uses_resume() +; RESULT-SAME: personality ptr @__gxx_personality_v0 +define void @uses_resume() personality ptr @__gxx_personality_v0 { +entry: + resume { ptr, i32 } zeroinitializer +} + +declare i32 @__gxx_personality_v0(...) +declare i32 @__CxxFrameHandler3(...) Index: llvm/tools/llvm-reduce/DeltaManager.cpp =================================================================== --- llvm/tools/llvm-reduce/DeltaManager.cpp +++ llvm/tools/llvm-reduce/DeltaManager.cpp @@ -81,6 +81,7 @@ DELTA_PASS("unreachable-basic-blocks", reduceUnreachableBasicBlocksDeltaPass) \ DELTA_PASS("basic-blocks", reduceBasicBlocksDeltaPass) \ DELTA_PASS("simplify-cfg", reduceUsingSimplifyCFGDeltaPass) \ + DELTA_PASS("function-data", reduceFunctionDataDeltaPass) \ DELTA_PASS("global-values", reduceGlobalValuesDeltaPass) \ DELTA_PASS("global-objects", reduceGlobalObjectsDeltaPass) \ DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass) \ Index: llvm/tools/llvm-reduce/deltas/ReduceFunctionBodies.h =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceFunctionBodies.h +++ llvm/tools/llvm-reduce/deltas/ReduceFunctionBodies.h @@ -18,6 +18,7 @@ namespace llvm { void reduceFunctionBodiesDeltaPass(TestRunner &Test); +void reduceFunctionDataDeltaPass(TestRunner &Test); } // namespace llvm #endif Index: llvm/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp +++ llvm/tools/llvm-reduce/deltas/ReduceFunctionBodies.cpp @@ -15,6 +15,7 @@ #include "Delta.h" #include "Utils.h" #include "llvm/IR/GlobalValue.h" +#include "llvm/IR/Instructions.h" using namespace llvm; @@ -34,3 +35,26 @@ runDeltaPass(Test, extractFunctionBodiesFromModule, "Reducing Function Bodies"); } + +static void reduceFunctionData(Oracle &O, Module &M) { + for (Function &F : M) { + if (F.isDeclaration()) + continue; + + if (F.hasPersonalityFn()) { + if (none_of(F, + [](const BasicBlock &BB) { + return BB.isEHPad() || isa(BB.getTerminator()); + }) && + !O.shouldKeep()) { + F.setPersonalityFn(nullptr); + } + } + + // TODO: Handle prefix data and prologue data + } +} + +void llvm::reduceFunctionDataDeltaPass(TestRunner &Test) { + runDeltaPass(Test, reduceFunctionData, "Reducing Function Data"); +}