Index: llvm/test/tools/llvm-reduce/remove-ifunc.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/remove-ifunc.ll @@ -0,0 +1,76 @@ +; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=ifuncs --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck --check-prefixes=CHECK-FINAL --input-file=%t %s + +; CHECK-INTERESTINGNESS: @ifunc1 = ifunc + +; CHECK-FINAL: @ifunc1 = ifunc void (), ptr @fn1 +@ifunc1 = ifunc void (), ptr @fn1 +@ifunc2 = ifunc void (), ptr @fn1 + +; CHECK-INTERESTINGNESS: @ifunc3 = +; CHECK-FINAL: @ifunc3 = ifunc i32 (double), ptr @fn2 +@ifunc3 = ifunc i32 (double), ptr @fn2 +@ifunc4 = ifunc float (i64), ptr @fn2 + + +; Make sure the hidden is preserved +; CHECK-INTERESTINGNESS: @ifunc5 = +; CHECK-FINAL: @ifunc5 = hidden ifunc i32 (double), ptr @fn3 +@ifunc5 = hidden ifunc i32 (double), ptr @fn3 +@ifunc6 = ifunc float (i64), ptr @fn4 + + +; Test ifunc to alias +; CHECK-INTERESTINGNESS: @ifunc7 = +; CHECK-FINAL: @ifunc7 = ifunc float (i64), ptr @ifunc_alias +; CHECK-NOT: @ifunc8 +@ifunc_alias = alias void (), ptr @aliasee +@ifunc7 = ifunc float (i64), ptr @ifunc_alias +@ifunc8 = ifunc float (i64), ptr @ifunc_alias + +define void @fn1() { + ret void +} + +define i32 @fn2(double %arg) { + ret i32 0 +} + +define i32 @fn3(double %arg) { + ret i32 1 +} + + +; Test call to removed ifunc + +; CHECK-INTERESTINGNESS-LABEL: define float @fn4( +; CHECK-INTERESTINGNESS: call float +; CHECK-FINAL: define float @fn4(i64 %arg) { +; CHECK-FINAL: %call = call float @fn4(i64 %arg) +define float @fn4(i64 %arg) { + %call = call float @ifunc6(i64 %arg) + ret float %call +} + +; Test call to removed bitcasted ifunc + +; CHECK-INTERESTINGNESS-LABEL: define i32 @fn5( +; CHECK-INTERESTINGNESS: call i32 +; CHECK-FINAL: define i32 @fn5(double %arg) { +; CHECK-FINAL: %call = call i32 @fn4(double %arg) +define i32 @fn5(double %arg) { + %call = call i32 bitcast (float(i64)* @ifunc6 to float(i64)*)(double %arg) + ret i32 %call +} + +; CHECK-INTERESTINGNESS: define void @aliasee() +define void @aliasee() { + ret void +} + +; CHECK-FINAL-LABEL: define float @call_ifunc_aliasee( +; CHECK-FINAL: %call = call float @ifunc_alias(i64 %arg) +define float @call_ifunc_aliasee(i64 %arg) { + %call = call float @ifunc8(i64 %arg) + ret float %call +} Index: llvm/tools/llvm-reduce/DeltaManager.cpp =================================================================== --- llvm/tools/llvm-reduce/DeltaManager.cpp +++ llvm/tools/llvm-reduce/DeltaManager.cpp @@ -74,6 +74,7 @@ DELTA_PASS("function-bodies", reduceFunctionBodiesDeltaPass) \ DELTA_PASS("special-globals", reduceSpecialGlobalsDeltaPass) \ DELTA_PASS("aliases", reduceAliasesDeltaPass) \ + DELTA_PASS("ifuncs", reduceIFuncsDeltaPass) \ DELTA_PASS("simplify-conditionals-true", reduceConditionalsTrueDeltaPass) \ DELTA_PASS("simplify-conditionals-false", reduceConditionalsFalseDeltaPass)\ DELTA_PASS("unreachable-basic-blocks", reduceUnreachableBasicBlocksDeltaPass) \ Index: llvm/tools/llvm-reduce/deltas/ReduceAliases.h =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceAliases.h +++ llvm/tools/llvm-reduce/deltas/ReduceAliases.h @@ -18,6 +18,7 @@ namespace llvm { void reduceAliasesDeltaPass(TestRunner &Test); +void reduceIFuncsDeltaPass(TestRunner &Test); } // namespace llvm #endif Index: llvm/tools/llvm-reduce/deltas/ReduceAliases.cpp =================================================================== --- llvm/tools/llvm-reduce/deltas/ReduceAliases.cpp +++ llvm/tools/llvm-reduce/deltas/ReduceAliases.cpp @@ -29,6 +29,20 @@ } } +static void extractIFuncsFromModule(Oracle &O, Module &Program) { + for (GlobalIFunc &GI : make_early_inc_range(Program.ifuncs())) { + if (!O.shouldKeep()) { + Constant *Resolver = GI.getResolver(); + GI.replaceAllUsesWith(Resolver); + GI.eraseFromParent(); + } + } +} + void llvm::reduceAliasesDeltaPass(TestRunner &Test) { runDeltaPass(Test, extractAliasesFromModule, "Reducing Aliases"); } + +void llvm::reduceIFuncsDeltaPass(TestRunner &Test) { + runDeltaPass(Test, extractIFuncsFromModule, "Reducing Ifuncs"); +}