diff --git a/llvm/test/tools/llvm-reduce/no-replace-intrinsic-callee-with-undef.ll b/llvm/test/tools/llvm-reduce/no-replace-intrinsic-callee-with-undef.ll --- a/llvm/test/tools/llvm-reduce/no-replace-intrinsic-callee-with-undef.ll +++ b/llvm/test/tools/llvm-reduce/no-replace-intrinsic-callee-with-undef.ll @@ -3,11 +3,11 @@ ; not replaced. The whole call instruction can be removed by instruction ; reduction instead. -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2> %t.log +; RUN: llvm-reduce --delta-passes=functions,instructions --test FileCheck --test-arg --check-prefixes=ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t 2> %t.log ; RUN: FileCheck -implicit-check-not=uninteresting --check-prefixes=ALL,CHECK-FINAL %s < %t ; Check that the call is removed by instruction reduction passes -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefix=ALL --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=functions,instructions --test FileCheck --test-arg --check-prefix=ALL --test-arg %s --test-arg --input-file %s -o %t ; RUN: FileCheck -implicit-check-not=uninteresting --check-prefixes=ALL,CHECK-NOCALL %s < %t diff --git a/llvm/test/tools/llvm-reduce/remove-all-of-multiple-args.ll b/llvm/test/tools/llvm-reduce/remove-all-of-multiple-args.ll --- a/llvm/test/tools/llvm-reduce/remove-all-of-multiple-args.ll +++ b/llvm/test/tools/llvm-reduce/remove-all-of-multiple-args.ll @@ -1,4 +1,4 @@ -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=arguments --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s define i32 @t(i32 %a0, i32 %a1, i32 %a2) { diff --git a/llvm/test/tools/llvm-reduce/remove-args-2.ll b/llvm/test/tools/llvm-reduce/remove-args-2.ll --- a/llvm/test/tools/llvm-reduce/remove-args-2.ll +++ b/llvm/test/tools/llvm-reduce/remove-args-2.ll @@ -1,7 +1,7 @@ ; Test that llvm-reduce can remove uninteresting function arguments from function definitions as well as their calls. ; This test checks that functions with different argument types are handled correctly ; -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=arguments --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s --input-file %t %struct.foo = type { %struct.foo*, i32, i32, i8* } diff --git a/llvm/test/tools/llvm-reduce/remove-args-used-by-ret.ll b/llvm/test/tools/llvm-reduce/remove-args-used-by-ret.ll --- a/llvm/test/tools/llvm-reduce/remove-args-used-by-ret.ll +++ b/llvm/test/tools/llvm-reduce/remove-args-used-by-ret.ll @@ -1,4 +1,4 @@ -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=arguments --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s ; We can't drop arguments if they are used by terminator instructions. diff --git a/llvm/test/tools/llvm-reduce/remove-args.ll b/llvm/test/tools/llvm-reduce/remove-args.ll --- a/llvm/test/tools/llvm-reduce/remove-args.ll +++ b/llvm/test/tools/llvm-reduce/remove-args.ll @@ -1,6 +1,6 @@ ; Test that llvm-reduce can remove uninteresting function arguments from function definitions as well as their calls. ; -; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-args.py %s -o %t +; RUN: llvm-reduce -delta-passes=arguments --test %python --test-arg %p/Inputs/remove-args.py %s -o %t ; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s ; CHECK: @interesting(i32 %interesting) diff --git a/llvm/test/tools/llvm-reduce/remove-bbs-ret-nonvoid.ll b/llvm/test/tools/llvm-reduce/remove-bbs-ret-nonvoid.ll --- a/llvm/test/tools/llvm-reduce/remove-bbs-ret-nonvoid.ll +++ b/llvm/test/tools/llvm-reduce/remove-bbs-ret-nonvoid.ll @@ -1,14 +1,14 @@ ; Test that llvm-reduce inserts valid return instructions for functions with ; on-void return types. ; -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck %s ; CHECK-INTERESTINGNESS: interesting: ; CHECK-INTERESTINGNESS: interesting2: define i32 @main(i1 %c) { -; CHECK-LABEL: define i32 @main() { +; CHECK-LABEL: define i32 @main(i1 %c) { ; CHECK-LABEL: interesting: ; CHECK-NEXT: br label %interesting2 diff --git a/llvm/test/tools/llvm-reduce/remove-bbs-unwinded-to.ll b/llvm/test/tools/llvm-reduce/remove-bbs-unwinded-to.ll --- a/llvm/test/tools/llvm-reduce/remove-bbs-unwinded-to.ll +++ b/llvm/test/tools/llvm-reduce/remove-bbs-unwinded-to.ll @@ -1,4 +1,4 @@ -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=basic-blocks --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s declare i32 @maybe_throwing_callee() diff --git a/llvm/test/tools/llvm-reduce/remove-bbs.ll b/llvm/test/tools/llvm-reduce/remove-bbs.ll --- a/llvm/test/tools/llvm-reduce/remove-bbs.ll +++ b/llvm/test/tools/llvm-reduce/remove-bbs.ll @@ -1,7 +1,7 @@ ; Test that llvm-reduce can remove uninteresting Basic Blocks, and remove them from instructions (i.e. SwitchInst, BranchInst and IndirectBrInst) ; Note: if an uninteresting BB is the default case for a switch, the instruction is removed altogether (since the default case cannot be replaced) ; -; RUN: llvm-reduce --test %python --test-arg %p/Inputs/remove-bbs.py %s -o %t +; RUN: llvm-reduce --delta-passes=basic-blocks --test %python --test-arg %p/Inputs/remove-bbs.py %s -o %t ; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s define void @main() { diff --git a/llvm/test/tools/llvm-reduce/remove-funcs.ll b/llvm/test/tools/llvm-reduce/remove-funcs.ll --- a/llvm/test/tools/llvm-reduce/remove-funcs.ll +++ b/llvm/test/tools/llvm-reduce/remove-funcs.ll @@ -1,7 +1,7 @@ ; Test that llvm-reduce can remove uninteresting functions as well as ; their InstCalls. ; -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=functions,instructions --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck -implicit-check-not=uninteresting --check-prefixes=CHECK-ALL,CHECK-FINAL %s define i32 @uninteresting1() { diff --git a/llvm/test/tools/llvm-reduce/remove-function-arguments-of-funcs-used-in-blockaddress.ll b/llvm/test/tools/llvm-reduce/remove-function-arguments-of-funcs-used-in-blockaddress.ll --- a/llvm/test/tools/llvm-reduce/remove-function-arguments-of-funcs-used-in-blockaddress.ll +++ b/llvm/test/tools/llvm-reduce/remove-function-arguments-of-funcs-used-in-blockaddress.ll @@ -1,4 +1,4 @@ -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=arguments --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s ; CHECK-INTERESTINGNESS: define void @func( diff --git a/llvm/test/tools/llvm-reduce/remove-global-vars.ll b/llvm/test/tools/llvm-reduce/remove-global-vars.ll --- a/llvm/test/tools/llvm-reduce/remove-global-vars.ll +++ b/llvm/test/tools/llvm-reduce/remove-global-vars.ll @@ -1,7 +1,7 @@ ; Test that llvm-reduce can remove uninteresting Global Variables as well as ; their direct uses (which in turn are replaced with 'undef'). -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=global-variables,global-initializers --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL --implicit-check-not=uninteresting %s $interesting5 = comdat any diff --git a/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll b/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll --- a/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll +++ b/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll @@ -22,8 +22,8 @@ define void @caller(i32 %arg) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { ; CHECK-ALL: bb: bb: -; CHECK-INTERESTINGNESS: %i0 = invoke i32 -; CHECK-FINAL: %i0 = invoke i32 bitcast (i32 ()* @maybe_throwing_callee to i32 (i32)*)(i32 %arg) +; CHECK-INTERESTINGNESS: %i0 = invoke i32 {{.*}}@maybe_throwing_callee +; CHECK-FINAL: %i0 = invoke i32 bitcast (i32 ()* @maybe_throwing_callee to i32 (i32)*) ; CHECK-ALL: to label %bb3 unwind label %bb1 %i0 = invoke i32 @maybe_throwing_callee(i32 %arg) to label %bb3 unwind label %bb1 diff --git a/llvm/test/tools/llvm-reduce/remove-operands.ll b/llvm/test/tools/llvm-reduce/remove-operands.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-reduce/remove-operands.ll @@ -0,0 +1,20 @@ +; Test that llvm-reduce can reduce operands to their default values. +; +; RUN: llvm-reduce --delta-passes=operands --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: cat %t | FileCheck %s + +; CHECK-INTERESTINGNESS: ret i32 + +; CHECK-LABEL: define i32 @main() { +define i32 @main() { + +; CHECK-LABEL: lb1: +; CHECK-NEXT: br label %lb2 +lb1: + br label %lb2 + +; CHECK-LABEL: lb2: +; CHECK-NEXT: ret i32 undef +lb2: + ret i32 10 +} diff --git a/llvm/test/tools/llvm-reduce/remove-single-arg.ll b/llvm/test/tools/llvm-reduce/remove-single-arg.ll --- a/llvm/test/tools/llvm-reduce/remove-single-arg.ll +++ b/llvm/test/tools/llvm-reduce/remove-single-arg.ll @@ -1,4 +1,4 @@ -; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: llvm-reduce --delta-passes=arguments --test FileCheck --test-arg --check-prefixes=CHECK-ALL,CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t ; RUN: cat %t | FileCheck --check-prefixes=CHECK-ALL,CHECK-FINAL %s define i32 @t(i32 %a0) { diff --git a/llvm/tools/llvm-reduce/CMakeLists.txt b/llvm/tools/llvm-reduce/CMakeLists.txt --- a/llvm/tools/llvm-reduce/CMakeLists.txt +++ b/llvm/tools/llvm-reduce/CMakeLists.txt @@ -28,6 +28,7 @@ deltas/ReduceModuleData.cpp deltas/ReduceOperandBundles.cpp deltas/ReduceSpecialGlobals.cpp + deltas/ReduceOperands.cpp llvm-reduce.cpp DEPENDS diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp --- a/llvm/tools/llvm-reduce/DeltaManager.cpp +++ b/llvm/tools/llvm-reduce/DeltaManager.cpp @@ -27,6 +27,7 @@ #include "deltas/ReduceMetadata.h" #include "deltas/ReduceModuleData.h" #include "deltas/ReduceOperandBundles.h" +#include "deltas/ReduceOperands.h" #include "deltas/ReduceSpecialGlobals.h" #include "llvm/Support/CommandLine.h" @@ -49,6 +50,7 @@ DELTA_PASS("metadata", reduceMetadataDeltaPass) \ DELTA_PASS("arguments", reduceArgumentsDeltaPass) \ DELTA_PASS("instructions", reduceInstructionsDeltaPass) \ + DELTA_PASS("operands", reduceOperandsDeltaPass) \ DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \ DELTA_PASS("attributes", reduceAttributesDeltaPass) \ DELTA_PASS("module-data", reduceModuleDataDeltaPass) diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.h b/llvm/tools/llvm-reduce/deltas/ReduceOperands.h new file mode 100755 --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceOperands.h @@ -0,0 +1,22 @@ +//===- ReduceOperands.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 to reduce operands to undef. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEOPERANDS_H +#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_REDUCEOPERANDS_H + +#include "Delta.h" + +namespace llvm { +void reduceOperandsDeltaPass(TestRunner &Test); +} // namespace llvm + +#endif diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp new file mode 100755 --- /dev/null +++ b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp @@ -0,0 +1,74 @@ +//===- ReduceOperands.cpp - 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 to reduce operands to undef. +// +//===----------------------------------------------------------------------===// + +#include "ReduceOperands.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/InstIterator.h" + +using namespace llvm; + +/// Returns if the given operand is undef. +static bool operandIsUndefValue(Use &Op) { + if (auto *C = dyn_cast(Op)) { + return isa(C); + } + return false; +} + +/// Returns if an operand can be reduced to undef. +/// TODO: make this logic check what types are reducible rather than +/// check what types that are not reducible. +static bool canReduceOperand(Use &Op) { + auto *Ty = Op->getType(); + // Can't reduce labels to undef + return !Ty->isLabelTy() && !operandIsUndefValue(Op); +} + +/// Sets Operands to undef. +static void extractOperandsFromModule(std::vector ChunksToKeep, + Module *Program) { + Oracle O(ChunksToKeep); + + // Extract Operands from the module. + for (auto &F : Program->functions()) { + for (auto &I : instructions(&F)) { + for (auto &Op : I.operands()) { + // Filter Operands then set to undef. + if (canReduceOperand(Op) && !O.shouldKeep()) { + auto *Ty = Op->getType(); + Op.set(UndefValue::get(Ty)); + } + } + } + } +} + +/// Counts the amount of operands in the module that can be reduced. +static int countOperands(Module *Program) { + int Count = 0; + for (auto &F : Program->functions()) { + for (auto &I : instructions(&F)) { + for (auto &Op : I.operands()) { + if (canReduceOperand(Op)) { + Count++; + } + } + } + } + return Count; +} + +void llvm::reduceOperandsDeltaPass(TestRunner &Test) { + errs() << "*** Reducing Operands...\n"; + int Count = countOperands(Test.getProgram()); + runDeltaPass(Test, Count, extractOperandsFromModule); +} diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/tools/llvm-reduce/BUILD.gn @@ -26,6 +26,7 @@ "deltas/ReduceModuleData.cpp", "deltas/ReduceOperandBundles.cpp", "deltas/ReduceSpecialGlobals.cpp", + "deltas/ReduceOperands.cpp", "llvm-reduce.cpp", ] }