[llvm] 9660563 - [llvm-reduce] Add reduction passes to reduce operands to undef/1/0
Arthur Eubanks via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 19 15:25:30 PDT 2021
Author: Arthur Eubanks
Date: 2021-10-19T15:25:21-07:00
New Revision: 9660563950aaed54020bfdf0be07e7096a9553e4
URL: https://github.com/llvm/llvm-project/commit/9660563950aaed54020bfdf0be07e7096a9553e4
DIFF: https://github.com/llvm/llvm-project/commit/9660563950aaed54020bfdf0be07e7096a9553e4.diff
LOG: [llvm-reduce] Add reduction passes to reduce operands to undef/1/0
Having non-undef constants in a final llvm-reduce output is nicer than
having undefs.
This splits the existing reduce-operands pass into three, one which does
the same as the current pass of reducing to undef, and two more to
reduce to the constant 1 and the constant 0. Do not reduce to undef if
the operand is a ConstantData, and do not reduce 0s to 1s.
Reducing GEP operands very frequently causes invalid IR (since types may
not match up if we index differently into a struct), so don't touch GEPs.
Reviewed By: Meinersbur
Differential Revision: https://reviews.llvm.org/D111765
Added:
Modified:
llvm/test/tools/llvm-reduce/remove-invoked-functions.ll
llvm/test/tools/llvm-reduce/remove-operands.ll
llvm/tools/llvm-reduce/DeltaManager.cpp
llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
llvm/tools/llvm-reduce/deltas/ReduceOperands.h
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll b/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll
index 0d3f8f87fd4a9..4cc6f71c27e84 100644
--- a/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll
+++ b/llvm/test/tools/llvm-reduce/remove-invoked-functions.ll
@@ -6,7 +6,7 @@
define i32 @maybe_throwing_callee(i32 %arg) {
; CHECK-ALL: call void @thrown()
; CHECK-INTERESTINGNESS: ret i32
-; CHECK-FINAL: ret i32 undef
+; CHECK-FINAL: ret i32 0
call void @thrown()
ret i32 %arg
}
diff --git a/llvm/test/tools/llvm-reduce/remove-operands.ll b/llvm/test/tools/llvm-reduce/remove-operands.ll
index 463f857dbb33b..bbae8c1b4128d 100644
--- a/llvm/test/tools/llvm-reduce/remove-operands.ll
+++ b/llvm/test/tools/llvm-reduce/remove-operands.ll
@@ -1,20 +1,52 @@
-; Test that llvm-reduce can reduce operands to their default values.
+; Test that llvm-reduce can reduce operands
;
-; 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
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-undef --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,UNDEF
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-one --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,ONE
+; RUN: llvm-reduce --abort-on-invalid-reduction --delta-passes=operands-zero --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,ZERO
+; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t
+; RUN: cat %t | FileCheck %s --check-prefixes=CHECK,ZERO
+; CHECK-INTERESTINGNESS: inttoptr
+; CHECK-INTERESTINGNESS: inttoptr
+; CHECK-INTERESTINGNESS: inttoptr
+; CHECK-INTERESTINGNESS: inttoptr
+; CHECK-INTERESTINGNESS: br label
; CHECK-INTERESTINGNESS: ret i32
-; CHECK-LABEL: define i32 @main() {
-define i32 @main() {
+%t = type { i32, i8 }
+
+; CHECK-LABEL: define i32 @main
+define i32 @main(%t* %a, i32 %a2) {
; CHECK-LABEL: lb1:
-; CHECK-NEXT: br label %lb2
+; UNDEF: inttoptr i16 0
+; UNDEF: inttoptr i16 1
+; UNDEF: inttoptr i16 2
+; UNDEF: inttoptr i16 undef
+; ONE: inttoptr i16 0
+; ONE: inttoptr i16 1
+; ONE: inttoptr i16 1
+; ONE: inttoptr i16 1
+; ZERO: inttoptr i16 0
+; ZERO: inttoptr i16 0
+; ZERO: inttoptr i16 0
+; ZERO: inttoptr i16 0
+; CHECK: br label %lb2
lb1:
+ %b = getelementptr %t, %t* %a, i32 1, i32 0
+ %i1 = inttoptr i16 0 to i8*
+ %i2 = inttoptr i16 1 to i8*
+ %i3 = inttoptr i16 2 to i8*
+ %i4 = inttoptr i16 undef to i8*
br label %lb2
; CHECK-LABEL: lb2:
-; CHECK-NEXT: ret i32 undef
+; UNDEF: ret i32 undef
+; ONE: ret i32 1
+; ZERO: ret i32 0
lb2:
- ret i32 10
+ ret i32 %a2
}
diff --git a/llvm/tools/llvm-reduce/DeltaManager.cpp b/llvm/tools/llvm-reduce/DeltaManager.cpp
index 676e2606de027..dab404094629d 100644
--- a/llvm/tools/llvm-reduce/DeltaManager.cpp
+++ b/llvm/tools/llvm-reduce/DeltaManager.cpp
@@ -51,7 +51,9 @@ static cl::opt<std::string>
DELTA_PASS("metadata", reduceMetadataDeltaPass) \
DELTA_PASS("arguments", reduceArgumentsDeltaPass) \
DELTA_PASS("instructions", reduceInstructionsDeltaPass) \
- DELTA_PASS("operands", reduceOperandsDeltaPass) \
+ DELTA_PASS("operands-zero", reduceOperandsZeroDeltaPass) \
+ DELTA_PASS("operands-one", reduceOperandsOneDeltaPass) \
+ DELTA_PASS("operands-undef", reduceOperandsUndefDeltaPass) \
DELTA_PASS("operands-to-args", reduceOperandsToArgsDeltaPass) \
DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \
DELTA_PASS("attributes", reduceAttributesDeltaPass) \
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
index f697746909e1e..dad0647bc6d21 100755
--- a/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
+++ b/llvm/tools/llvm-reduce/deltas/ReduceOperands.cpp
@@ -1,71 +1,105 @@
-//===- 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"
+#include "llvm/IR/Operator.h"
+#include "llvm/IR/Type.h"
using namespace llvm;
-/// Returns if the given operand is undef.
-static bool operandIsUndefValue(Use &Op) {
- if (auto *C = dyn_cast<Constant>(Op)) {
- return isa<UndefValue>(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(Oracle &O, Module &Program) {
- // Extract Operands from the module.
+static void
+extractOperandsFromModule(Oracle &O, Module &Program,
+ function_ref<Value *(Use &)> ReduceValue) {
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));
- }
+ Value *Reduced = ReduceValue(Op);
+ if (Reduced && !O.shouldKeep())
+ Op.set(Reduced);
}
}
}
}
-/// Counts the amount of operands in the module that can be reduced.
-static int countOperands(Module &Program) {
+static int countOperands(Module &Program,
+ function_ref<Value *(Use &)> ReduceValue) {
int Count = 0;
for (auto &F : Program.functions()) {
for (auto &I : instructions(&F)) {
for (auto &Op : I.operands()) {
- if (canReduceOperand(Op)) {
+ if (ReduceValue(Op))
Count++;
- }
}
}
}
return Count;
}
-void llvm::reduceOperandsDeltaPass(TestRunner &Test) {
- errs() << "*** Reducing Operands...\n";
- int Count = countOperands(Test.getProgram());
- runDeltaPass(Test, Count, extractOperandsFromModule);
+static bool isOne(Use &Op) {
+ auto *C = dyn_cast<Constant>(Op);
+ return C && C->isOneValue();
+}
+
+static bool isZero(Use &Op) {
+ auto *C = dyn_cast<Constant>(Op);
+ return C && C->isNullValue();
+}
+
+void llvm::reduceOperandsUndefDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Operands to undef...\n";
+ auto ReduceValue = [](Use &Op) -> Value * {
+ if (isa<GEPOperator>(Op.getUser()))
+ return nullptr;
+ if (Op->getType()->isLabelTy())
+ return nullptr;
+ // Don't replace existing ConstantData Uses.
+ return isa<ConstantData>(*Op) ? nullptr : UndefValue::get(Op->getType());
+ };
+ int Count = countOperands(Test.getProgram(), ReduceValue);
+ runDeltaPass(Test, Count, [ReduceValue](Oracle &O, Module &Program) {
+ extractOperandsFromModule(O, Program, ReduceValue);
+ });
+}
+
+void llvm::reduceOperandsOneDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Operands to one...\n";
+ auto ReduceValue = [](Use &Op) -> Value * {
+ // TODO: support floats
+ if (isa<GEPOperator>(Op.getUser()))
+ return nullptr;
+ auto *Ty = dyn_cast<IntegerType>(Op->getType());
+ if (!Ty)
+ return nullptr;
+ // Don't replace existing ones and zeroes.
+ return (isOne(Op) || isZero(Op)) ? nullptr : ConstantInt::get(Ty, 1);
+ };
+ int Count = countOperands(Test.getProgram(), ReduceValue);
+ runDeltaPass(Test, Count, [ReduceValue](Oracle &O, Module &Program) {
+ extractOperandsFromModule(O, Program, ReduceValue);
+ });
+}
+
+void llvm::reduceOperandsZeroDeltaPass(TestRunner &Test) {
+ errs() << "*** Reducing Operands to zero...\n";
+ auto ReduceValue = [](Use &Op) -> Value * {
+ // TODO: be more precise about which GEP operands we can reduce (e.g. array
+ // indexes)
+ if (isa<GEPOperator>(Op.getUser()))
+ return nullptr;
+ if (Op->getType()->isLabelTy())
+ return nullptr;
+ // Don't replace existing zeroes.
+ return isZero(Op) ? nullptr : Constant::getNullValue(Op->getType());
+ };
+ int Count = countOperands(Test.getProgram(), ReduceValue);
+ runDeltaPass(Test, Count, [ReduceValue](Oracle &O, Module &Program) {
+ extractOperandsFromModule(O, Program, ReduceValue);
+ });
}
diff --git a/llvm/tools/llvm-reduce/deltas/ReduceOperands.h b/llvm/tools/llvm-reduce/deltas/ReduceOperands.h
index 55c903babe322..18fdb07dd3fbb 100755
--- a/llvm/tools/llvm-reduce/deltas/ReduceOperands.h
+++ b/llvm/tools/llvm-reduce/deltas/ReduceOperands.h
@@ -1,14 +1,10 @@
-//===- 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
@@ -16,7 +12,9 @@
#include "Delta.h"
namespace llvm {
-void reduceOperandsDeltaPass(TestRunner &Test);
+void reduceOperandsUndefDeltaPass(TestRunner &Test);
+void reduceOperandsOneDeltaPass(TestRunner &Test);
+void reduceOperandsZeroDeltaPass(TestRunner &Test);
} // namespace llvm
#endif
More information about the llvm-commits
mailing list