Index: llvm/test/tools/llvm-reduce/reduce-using-passes.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-reduce/reduce-using-passes.ll @@ -0,0 +1,53 @@ +; the function below can be simplified by InstCombine + DSE to "ret +; 0". here we'll test the ability of reduceUsingOpt to run only +; InstCombine and not also DSE. + +; RUN: llvm-reduce --delta-passes=using-opt --abort-on-invalid-reduction --test FileCheck --test-arg --check-prefixes=INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: FileCheck %s --input-file=%t + +; INTERESTINGNESS: store i32 + +; CHECK: ret i32 0 + +%struct.foo = type { [2 x i32] } + +@g = dso_local global %struct.foo zeroinitializer, align 4 + +define dso_local i32 @test(i32 noundef %0, i32 noundef %1) { + %3 = alloca i32, align 4 + %4 = alloca i32, align 4 + %5 = alloca %struct.foo, align 4 + %6 = alloca i32, align 4 + %7 = alloca i32, align 4 + %8 = alloca i32, align 4 + store i32 %0, ptr %3, align 4 + store i32 %1, ptr %4, align 4 + call void @llvm.memcpy.p0.p0.i64(ptr align 4 %5, ptr align 4 @g, i64 8, i1 false) + %9 = load i32, ptr %3, align 4 + store i32 %9, ptr @g, align 4 + %10 = load i32, ptr %4, align 4 + store i32 %10, ptr getelementptr inbounds ([2 x i32], ptr @g, i64 0, i64 1), align 4 + %11 = load i32, ptr @g, align 4 + %12 = xor i32 %11, -1 + %13 = load i32, ptr getelementptr inbounds ([2 x i32], ptr @g, i64 0, i64 1), align 4 + %14 = xor i32 %13, -1 + %15 = or i32 %12, %14 + store i32 %15, ptr %6, align 4 + %16 = load i32, ptr @g, align 4 + %17 = xor i32 %16, -1 + %18 = load i32, ptr getelementptr inbounds ([2 x i32], ptr @g, i64 0, i64 1), align 4 + %19 = xor i32 %18, -1 + %20 = and i32 %17, %19 + store i32 %20, ptr %7, align 4 + %21 = load i32, ptr %6, align 4 + %22 = load i32, ptr %7, align 4 + %23 = and i32 %21, %22 + %24 = load i32, ptr @g, align 4 + %25 = and i32 %23, %24 + store i32 %25, ptr %8, align 4 + call void @llvm.memcpy.p0.p0.i64(ptr align 4 @g, ptr align 4 %5, i64 8, i1 false) + %26 = load i32, ptr %8, align 4 + ret i32 %26 +} + +declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 Index: llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsic-like-functions.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsic-like-functions.ll +++ llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsic-like-functions.ll @@ -19,7 +19,7 @@ ; CHECK-INTERESTINGNESS-SAME: %a ; CHECK-INTERESTINGNESS-SAME: #1 -; CHECK-FINAL: %r = call "arg0" i32 @llvm.not.really.an.intrinsic(i32 "arg3" %a, i32 %a) #1 +; CHECK-FINAL: %r = tail call "arg0" i32 @llvm.not.really.an.intrinsic(i32 "arg3" %a, i32 %a) #1 ; CHECK-ALL: ret i32 %r %r = call "arg0" "arg1" i32 @llvm.not.really.an.intrinsic(i32 "arg2" "arg3" %a, i32 %a) "arg4" "arg5" Index: llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsics.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsics.ll +++ llvm/test/tools/llvm-reduce/remove-attributes-from-intrinsics.ll @@ -16,7 +16,7 @@ ; CHECK-INTERESTINGNESS-SAME: %a ; CHECK-INTERESTINGNESS-SAME: #1 -; CHECK-FINAL: %r = call "arg0" i32 @llvm.uadd.sat.i32(i32 "arg3" %a, i32 %a) #1 +; CHECK-FINAL: %r = tail call "arg0" i32 @llvm.uadd.sat.i32(i32 "arg3" %a, i32 %a) #1 ; CHECK-ALL: ret i32 %r %r = call "arg0" "arg1" i32 @llvm.uadd.sat.i32(i32 "arg2" "arg3" %a, i32 %a) "arg4" "arg5" Index: llvm/test/tools/llvm-reduce/remove-function-bodies-used-in-globals.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-function-bodies-used-in-globals.ll +++ llvm/test/tools/llvm-reduce/remove-function-bodies-used-in-globals.ll @@ -5,7 +5,7 @@ ; (Aliasee should be either GlobalValue or ConstantExpr). ; CHECK-INTERESTINGNESS: @alias = -; CHECK-FINAL: @alias = alias void (i32), bitcast (void ()* @func to void (i32)*) +; CHECK-FINAL: @alias = internal alias void (i32), bitcast (void ()* @func to void (i32)*) @alias = alias void (i32), void (i32)* @func Index: llvm/test/tools/llvm-reduce/remove-invoked-functions.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-invoked-functions.ll +++ llvm/test/tools/llvm-reduce/remove-invoked-functions.ll @@ -23,7 +23,7 @@ ; CHECK-ALL: bb: bb: ; CHECK-INTERESTINGNESS: %i0 = invoke i32 {{.*}}@maybe_throwing_callee -; CHECK-FINAL: %i0 = invoke i32 bitcast (i32 ()* @maybe_throwing_callee to i32 (i32)*) +; CHECK-FINAL: %i0 = invoke i32 @maybe_throwing_callee() ; CHECK-ALL: to label %bb3 unwind label %bb1 %i0 = invoke i32 @maybe_throwing_callee(i32 %arg) to label %bb3 unwind label %bb1 Index: llvm/test/tools/llvm-reduce/remove-operands-fp.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-operands-fp.ll +++ llvm/test/tools/llvm-reduce/remove-operands-fp.ll @@ -23,7 +23,7 @@ ; CHECK-INTERESTINGNESS: = fadd <2 x float> ; CHECK-INTERESTINGNESS: = fadd <2 x float> -; CHECK-LABEL: define void @foo( +; CHECK-LABEL: define {{(internal )?}}void @foo( ; ONE: %fadd0 = fadd float %arg0, 1.000000e+00 Index: llvm/test/tools/llvm-reduce/remove-operands.ll =================================================================== --- llvm/test/tools/llvm-reduce/remove-operands.ll +++ llvm/test/tools/llvm-reduce/remove-operands.ll @@ -18,7 +18,7 @@ declare void @llvm.foo(metadata) -; CHECK-LABEL: define i32 @main +; CHECK-LABEL: define {{(internal )?}}i32 @main define i32 @main(%t* %a, i32 %a2) { ; CHECK-LABEL: lb1: Index: llvm/tools/llvm-reduce/CMakeLists.txt =================================================================== --- llvm/tools/llvm-reduce/CMakeLists.txt +++ llvm/tools/llvm-reduce/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + AggressiveInstCombine AllTargetsAsmParsers AllTargetsCodeGens AllTargetsDescs @@ -8,9 +9,13 @@ BitWriter CodeGen Core + InstCombine + IPO IRReader MC MIRParser + Passes + ScalarOpts Support Target TransformUtils @@ -41,6 +46,7 @@ deltas/ReduceOperandsSkip.cpp deltas/ReduceOperandsToArgs.cpp deltas/ReduceInstructionsMIR.cpp + deltas/ReduceUsingOpt.cpp deltas/ReduceInstructionFlagsMIR.cpp deltas/ReduceIRReferences.cpp deltas/ReduceVirtualRegisters.cpp Index: llvm/tools/llvm-reduce/DeltaManager.cpp =================================================================== --- llvm/tools/llvm-reduce/DeltaManager.cpp +++ llvm/tools/llvm-reduce/DeltaManager.cpp @@ -37,6 +37,7 @@ #include "deltas/ReduceOperandsToArgs.h" #include "deltas/ReduceRegisterUses.h" #include "deltas/ReduceSpecialGlobals.h" +#include "deltas/ReduceUsingOpt.h" #include "deltas/ReduceVirtualRegisters.h" #include "deltas/SimplifyInstructions.h" #include "llvm/Support/CommandLine.h" @@ -51,6 +52,7 @@ cl::cat(LLVMReduceOptions)); #define DELTA_PASSES \ + DELTA_PASS("using-opt", reduceUsingOptDeltaPass) \ DELTA_PASS("special-globals", reduceSpecialGlobalsDeltaPass) \ DELTA_PASS("aliases", reduceAliasesDeltaPass) \ DELTA_PASS("function-bodies", reduceFunctionBodiesDeltaPass) \ Index: llvm/tools/llvm-reduce/deltas/ReduceUsingOpt.h =================================================================== --- /dev/null +++ llvm/tools/llvm-reduce/deltas/ReduceUsingOpt.h @@ -0,0 +1,24 @@ +//===- ReduceUsingOpt.h - Specialized Delta Pass --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements a function which calls the Generic Delta pass +// in order to call various optimization passes in order to simplify +// and canonicalize the code being reduced. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEUSINGOPT_H +#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEUSINGOPT_H + +#include "Delta.h" + +namespace llvm { +void reduceUsingOptDeltaPass(TestRunner &Test); +} // namespace llvm + +#endif Index: llvm/tools/llvm-reduce/deltas/ReduceUsingOpt.cpp =================================================================== --- /dev/null +++ llvm/tools/llvm-reduce/deltas/ReduceUsingOpt.cpp @@ -0,0 +1,154 @@ +//===- ReduceUsingOpt.h - Specialized Delta Pass --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements a function which calls the Generic Delta pass +// in order to call various optimization passes in order to simplify +// and canonicalize the code being reduced. +// +//===----------------------------------------------------------------------===// + +#include "ReduceUsingOpt.h" +#include "Delta.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/DeadArgumentElimination.h" +#include "llvm/Transforms/IPO/GlobalDCE.h" +#include "llvm/Transforms/IPO/GlobalOpt.h" +#include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/IPO/SCCP.h" +#include "llvm/Transforms/InstCombine/InstCombine.h" +#include "llvm/Transforms/Scalar/ADCE.h" +#include "llvm/Transforms/Scalar/BDCE.h" +#include "llvm/Transforms/Scalar/CorrelatedValuePropagation.h" +#include "llvm/Transforms/Scalar/DCE.h" +#include "llvm/Transforms/Scalar/DeadStoreElimination.h" +#include "llvm/Transforms/Scalar/EarlyCSE.h" +#include "llvm/Transforms/Scalar/GVN.h" +#include "llvm/Transforms/Scalar/IndVarSimplify.h" +#include "llvm/Transforms/Scalar/InstSimplifyPass.h" +#include "llvm/Transforms/Scalar/JumpThreading.h" +#include "llvm/Transforms/Scalar/LICM.h" +#include "llvm/Transforms/Scalar/LoopDeletion.h" +#include "llvm/Transforms/Scalar/LoopIdiomRecognize.h" +#include "llvm/Transforms/Scalar/LoopInstSimplify.h" +#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" +#include "llvm/Transforms/Scalar/MemCpyOptimizer.h" +#include "llvm/Transforms/Scalar/NewGVN.h" +#include "llvm/Transforms/Scalar/Reassociate.h" +#include "llvm/Transforms/Scalar/SCCP.h" +#include "llvm/Transforms/Scalar/SROA.h" +#include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h" +#include "llvm/Transforms/Scalar/SimplifyCFG.h" +#include "llvm/Transforms/Scalar/TailRecursionElimination.h" + +using namespace llvm; + +static std::vector> FunctionPasses = + { + [](FunctionPassManager &FPM) -> void { + FPM.addPass(InstSimplifyPass()); + }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(DCEPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(ADCEPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(BDCEPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(DSEPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(GVNPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(NewGVNPass()); }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(InstCombinePass()); + }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(AggressiveInstCombinePass()); + }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(JumpThreadingPass()); + }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(MemCpyOptPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(SROAPass()); }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(SCCPPass()); }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(SimplifyCFGPass()); + }, + [](FunctionPassManager &FPM) -> void { FPM.addPass(EarlyCSEPass()); }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(ReassociatePass()); + }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(CorrelatedValuePropagationPass()); + }, + [](FunctionPassManager &FPM) -> void { + FPM.addPass(TailCallElimPass()); + }, +}; + +static std::vector> LoopPasses = { + // MssaOptCap = 100 and MssaNoAccForPromotionCap = 250 are the + // default values found in LICM.cpp + [](LoopPassManager &LPM) -> void { LPM.addPass(LICMPass(100, 250, true)); }, + [](LoopPassManager &LPM) -> void { LPM.addPass(LoopDeletionPass()); }, + [](LoopPassManager &LPM) -> void { LPM.addPass(LoopInstSimplifyPass()); }, + [](LoopPassManager &LPM) -> void { LPM.addPass(LoopSimplifyCFGPass()); }, + [](LoopPassManager &LPM) -> void { LPM.addPass(SimpleLoopUnswitchPass()); }, + [](LoopPassManager &LPM) -> void { LPM.addPass(LoopIdiomRecognizePass()); }, + [](LoopPassManager &LPM) -> void { LPM.addPass(IndVarSimplifyPass()); }, +}; + +static std::vector> ModulePasses = { + [](ModulePassManager &MPM) -> void { MPM.addPass(GlobalDCEPass()); }, + [](ModulePassManager &MPM) -> void { + MPM.addPass(DeadArgumentEliminationPass()); + }, + [](ModulePassManager &MPM) -> void { MPM.addPass(GlobalOptPass()); }, + [](ModulePassManager &MPM) -> void { + MPM.addPass(ModuleInlinerWrapperPass()); + }, + [](ModulePassManager &MPM) -> void { MPM.addPass(InternalizePass()); }, + [](ModulePassManager &MPM) -> void { MPM.addPass(IPSCCPPass()); }, +}; + +static void runOptPasses(Oracle &O, Module &Program) { + PassBuilder PB; + + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModulePassManager MPM; + ModuleAnalysisManager MAM; + + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + FunctionPassManager FPM; + for (auto FP : FunctionPasses) + if (!O.shouldKeep()) + FP(FPM); + MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); + + LoopPassManager LPM; + for (auto LP : LoopPasses) + if (!O.shouldKeep()) + LP(LPM); + MPM.addPass(createModuleToFunctionPassAdaptor( + createFunctionToLoopPassAdaptor(std::move(LPM)))); + + for (auto MP : ModulePasses) + if (!O.shouldKeep()) + MP(MPM); + + MPM.run(Program, MAM); +} + +void llvm::reduceUsingOptDeltaPass(TestRunner &Test) { + outs() << "*** Reducing with Optimization Passes...\n"; + runDeltaPass(Test, runOptPasses); +}