stop llvm-reduce from introducing undefs

Differential Revision: https://reviews.llvm.org/D128317
This commit is contained in:
John Regehr
2022-06-21 17:30:52 -06:00
parent 1dd2c93a66
commit 2962f9df7c
22 changed files with 75 additions and 61 deletions

View File

@@ -20,7 +20,7 @@
; INTERESTING: store i32 %[[KEEP]], i32* @GlobalKeep, align 4
; INTERESTING-LABEL: define void @func_caller() {
; REDUCED: call void @func(i32 21, i32* undef, i32* undef, float* undef)
; REDUCED: call void @func(i32 21, i32* null, i32* null, float* null)
@Global = global i32 42

View File

@@ -6,7 +6,7 @@ define i32 @t(i32 %a0, i32 %a1, i32 %a2) {
; CHECK-FINAL: () {
;
; CHECK-INTERESTINGNESS: ret i32
; CHECK-FINAL: ret i32 undef
; CHECK-FINAL: ret i32 0
ret i32 %a1
}

View File

@@ -8,7 +8,7 @@ define i32 @t(i32 %a0, i32 %a1, i32 %a2) {
; CHECK-FINAL-NOT: %a1
;
; CHECK-INTERESTINGNESS: ret i32
; CHECK-FINAL: ret i32 undef
; CHECK-FINAL: ret i32 0
ret i32 %a1
}

View File

@@ -13,7 +13,7 @@ define i32 @main(i1 %c) {
; CHECK-NEXT: br label %interesting2
; CHECK-LABEL: interesting2:
; CHECK-NEXT: ret i32 undef
; CHECK-NEXT: ret i32 0
interesting:
br label %interesting2

View File

@@ -25,7 +25,7 @@ bb1:
; CHECK-ALL: bb3:
bb3:
; CHECK-INTERESTINGNESS: call void @did_not_throw(i32
; CHECK-FINAL: call void @did_not_throw(i32 undef)
; CHECK-FINAL: call void @did_not_throw(i32 0)
; CHECK-ALL: br label %bb4
call void @did_not_throw(i32 %i0)
br label %bb4

View File

@@ -1,5 +1,5 @@
; Test that llvm-reduce can remove uninteresting Global Variables as well as
; their direct uses (which in turn are replaced with 'undef').
; their direct uses (which in turn are replaced with '0').
; 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
@@ -31,11 +31,11 @@ entry:
%0 = load i32, i32* @uninteresting, align 4
; CHECK-INTERESTINGNESS: store i32 {{.*}}, i32* @interesting, align 4
; CHECK-FINAL: store i32 undef, i32* @interesting, align 4
; CHECK-FINAL: store i32 0, i32* @interesting, align 4
store i32 %0, i32* @interesting, align 4
; CHECK-INTERESTINGNESS: store i32 {{.*}}, i32* @interesting3, align 4
; CHECK-FINAL: store i32 undef, i32* @interesting3, align 4
; CHECK-FINAL: store i32 0, i32* @interesting3, align 4
store i32 %0, i32* @interesting3, align 4
; CHECK-ALL: load i32, i32* @interesting, align 4

View File

@@ -1,8 +1,5 @@
; Test that llvm-reduce can reduce floating point operands
;
; 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: FileCheck --check-prefixes=CHECK,UNDEF %s < %t
; 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: FileCheck --check-prefixes=CHECK,ONE %s < %t
@@ -28,19 +25,6 @@
; CHECK-LABEL: define void @foo(
; UNDEF: %fadd0 = fadd float %arg0, undef
; UNDEF: %fadd1 = fadd float undef, undef
; UNDEF: %fadd2 = fadd float undef, 0.000000e+00
; UNDEF: %fadd3 = fadd float undef, 1.000000e+00
; UNDEF: %fadd4 = fadd float undef, 0x7FF8000000000000
; UNDEF: %fadd5 = fadd float undef, undef
; UNDEF: %fadd6 = fadd <2 x float> %arg2, undef
; UNDEF: %fadd7 = fadd <2 x float> undef, undef
; UNDEF: %fadd8 = fadd <2 x float> undef, zeroinitializer
; UNDEF: %fadd9 = fadd <2 x float> undef, <float 1.000000e+00, float 1.000000e+00>
; UNDEF: %fadd10 = fadd <2 x float> undef, undef
; UNDEF: %fadd11 = fadd <2 x float> undef, <float 0x7FF8000000000000, float 0x7FF8000000000000>
; ONE: %fadd0 = fadd float %arg0, 1.000000e+00
; ONE: %fadd1 = fadd float 1.000000e+00, 1.000000e+00

View File

@@ -1,7 +1,5 @@
; Test that llvm-reduce can reduce operands
;
; 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
@@ -24,10 +22,6 @@ declare void @llvm.foo(metadata)
define i32 @main(%t* %a, i32 %a2) {
; CHECK-LABEL: lb1:
; 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
@@ -47,7 +41,6 @@ lb1:
br label %lb2
; CHECK-LABEL: lb2:
; UNDEF: ret i32 undef
; ONE: ret i32 1
; ZERO: ret i32 0
lb2:

View File

@@ -21,6 +21,7 @@ add_llvm_tool(llvm-reduce
ReducerWorkItem.cpp
TestRunner.cpp
deltas/Delta.cpp
deltas/Utils.cpp
deltas/ReduceAliases.cpp
deltas/ReduceArguments.cpp
deltas/ReduceAttributes.cpp

View File

@@ -66,7 +66,6 @@ static cl::opt<std::string>
DELTA_PASS("simplify-instructions", simplifyInstructionsDeltaPass) \
DELTA_PASS("operands-zero", reduceOperandsZeroDeltaPass) \
DELTA_PASS("operands-one", reduceOperandsOneDeltaPass) \
DELTA_PASS("operands-undef", reduceOperandsUndefDeltaPass) \
DELTA_PASS("operands-to-args", reduceOperandsToArgsDeltaPass) \
DELTA_PASS("operands-skip", reduceOperandsSkipDeltaPass) \
DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \

View File

@@ -13,6 +13,7 @@
#include "ReduceArguments.h"
#include "Delta.h"
#include "Utils.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
@@ -79,7 +80,7 @@ static void extractArgumentsFromModule(Oracle &O, Module &Program) {
if (!ArgsToKeep.count(&A)) {
// By adding undesired arguments to the VMap, CloneFunction will remove
// them from the resulting Function
VMap[&A] = UndefValue::get(A.getType());
VMap[&A] = getDefaultValue(A.getType());
for (auto *U : A.users())
if (auto *I = dyn_cast<Instruction>(*&U))
InstToDelete.push_back(I);
@@ -89,7 +90,7 @@ static void extractArgumentsFromModule(Oracle &O, Module &Program) {
if (!V)
continue;
auto *I = cast<Instruction>(V);
I->replaceAllUsesWith(UndefValue::get(I->getType()));
I->replaceAllUsesWith(getDefaultValue(I->getType()));
if (!I->isTerminator())
I->eraseFromParent();
}

View File

@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ReduceBasicBlocks.h"
#include "Utils.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constants.h"
@@ -43,7 +44,7 @@ static void replaceBranchTerminator(BasicBlock &BB,
if (auto *IndBI = dyn_cast<IndirectBrInst>(Term))
Address = IndBI->getAddress();
Term->replaceAllUsesWith(UndefValue::get(Term->getType()));
Term->replaceAllUsesWith(getDefaultValue(Term->getType()));
Term->eraseFromParent();
if (ChunkSuccessors.empty()) {
@@ -62,7 +63,7 @@ static void replaceBranchTerminator(BasicBlock &BB,
// If that fails then resort to replacing with a ret.
auto *FnRetTy = BB.getParent()->getReturnType();
ReturnInst::Create(BB.getContext(),
FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),
FnRetTy->isVoidTy() ? nullptr : getDefaultValue(FnRetTy),
&BB);
return;
}
@@ -87,7 +88,7 @@ removeUninterestingBBsFromSwitch(SwitchInst &SwInst,
if (!BBsToKeep.count(SwInst.getDefaultDest())) {
auto *FnRetTy = SwInst.getParent()->getParent()->getReturnType();
ReturnInst::Create(SwInst.getContext(),
FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),
FnRetTy->isVoidTy() ? nullptr : getDefaultValue(FnRetTy),
SwInst.getParent());
SwInst.eraseFromParent();
} else
@@ -133,7 +134,7 @@ static void extractBasicBlocksFromModule(Oracle &O, Module &Program) {
for (auto &BB : BBsToDelete) {
// Instructions might be referenced in other BBs
for (auto &I : *BB)
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.replaceAllUsesWith(getDefaultValue(I.getType()));
if (BB->getParent()->size() == 1) {
// this is the last basic block of the function, thus we must also make
// sure to remove comdat and set linkage to external

View File

@@ -14,6 +14,7 @@
#include "ReduceFunctions.h"
#include "Delta.h"
#include "Utils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instructions.h"
@@ -42,8 +43,8 @@ static void extractFunctionsFromModule(Oracle &O, Module &Program) {
// And finally, we can actually delete them.
for (Function &F : FuncsToRemove) {
// Replace all *still* remaining uses with undef.
F.replaceAllUsesWith(UndefValue::get(F.getType()));
// Replace all *still* remaining uses with the default value.
F.replaceAllUsesWith(getDefaultValue(F.getType()));
// And finally, fully drop it.
F.eraseFromParent();
}

View File

@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ReduceGlobalVars.h"
#include "Utils.h"
#include "llvm/IR/Constants.h"
#include <set>
@@ -40,7 +41,7 @@ static void extractGVsFromModule(Oracle &O, Module &Program) {
if (auto *Inst = dyn_cast<Instruction>(U))
InstToRemove.push_back(Inst);
GV.replaceAllUsesWith(UndefValue::get(GV.getType()));
GV.replaceAllUsesWith(getDefaultValue(GV.getType()));
ToRemove.push_back(&GV);
}
@@ -49,7 +50,7 @@ static void extractGVsFromModule(Oracle &O, Module &Program) {
if (!V)
continue;
auto *Inst = cast<Instruction>(V);
Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
Inst->replaceAllUsesWith(getDefaultValue(Inst->getType()));
Inst->eraseFromParent();
}

View File

@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "ReduceInstructions.h"
#include "Utils.h"
#include "llvm/IR/Constants.h"
using namespace llvm;
@@ -42,7 +43,7 @@ static void extractInstrFromModule(Oracle &O, Module &Program) {
for (auto &BB : F)
for (auto &Inst : BB)
if (!InstToKeep.count(&Inst)) {
Inst.replaceAllUsesWith(UndefValue::get(Inst.getType()));
Inst.replaceAllUsesWith(getDefaultValue(Inst.getType()));
InstToDelete.push_back(&Inst);
}

View File

@@ -62,19 +62,6 @@ static bool shouldReduceOperand(Use &Op) {
return true;
}
void llvm::reduceOperandsUndefDeltaPass(TestRunner &Test) {
errs() << "*** Reducing Operands to undef...\n";
auto ReduceValue = [](Use &Op) -> Value * {
if (!shouldReduceOperand(Op))
return nullptr;
// Don't replace existing ConstantData Uses.
return isa<ConstantData>(*Op) ? nullptr : UndefValue::get(Op->getType());
};
runDeltaPass(Test, [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 * {

View File

@@ -12,7 +12,6 @@
#include "Delta.h"
namespace llvm {
void reduceOperandsUndefDeltaPass(TestRunner &Test);
void reduceOperandsOneDeltaPass(TestRunner &Test);
void reduceOperandsZeroDeltaPass(TestRunner &Test);
} // namespace llvm

View File

@@ -61,7 +61,7 @@ static bool shouldReduceOperand(Use &Op) {
static int classifyReductivePower(Value *V) {
if (auto *C = dyn_cast<ConstantData>(V)) {
if (isa<UndefValue>(V))
return 4;
return -2;
if (C->isNullValue())
return 7;
if (C->isOneValue())

View File

@@ -8,6 +8,7 @@
#include "ReduceOperandsToArgs.h"
#include "Delta.h"
#include "Utils.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstIterator.h"
@@ -67,10 +68,10 @@ static void replaceFunctionCalls(Function *OldF, Function *NewF) {
// Call arguments for NewF.
SmallVector<Value *> Args(NewF->arg_size(), nullptr);
// Fill up the additional parameters with undef values.
// Fill up the additional parameters with default values.
for (auto ArgIdx : llvm::seq<size_t>(OldF->arg_size(), NewF->arg_size())) {
Type *NewArgTy = NewF->getArg(ArgIdx)->getType();
Args[ArgIdx] = UndefValue::get(NewArgTy);
Args[ArgIdx] = getDefaultValue(NewArgTy);
}
for (CallBase *CI : Callers) {

View File

@@ -16,6 +16,7 @@
#include "ReduceSpecialGlobals.h"
#include "Delta.h"
#include "Utils.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/GlobalValue.h"
@@ -29,7 +30,7 @@ static StringRef SpecialGlobalNames[] = {"llvm.used", "llvm.compiler.used"};
static void extractSpecialGlobalsFromModule(Oracle &O, Module &Program) {
for (StringRef Name : SpecialGlobalNames) {
if (auto *Used = Program.getNamedGlobal(Name)) {
Used->replaceAllUsesWith(UndefValue::get(Used->getType()));
Used->replaceAllUsesWith(getDefaultValue(Used->getType()));
Used->eraseFromParent();
}
}

View File

@@ -0,0 +1,20 @@
//===- Utils.cpp - llvm-reduce utility functions --------------------------===//
//
// 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 contains some utility functions supporting llvm-reduce.
//
//===----------------------------------------------------------------------===//
#include "Utils.h"
#include "llvm/IR/Constants.h"
using namespace llvm;
Value *llvm::getDefaultValue(Type *T) {
return T->isVoidTy() ? PoisonValue::get(T) : Constant::getNullValue(T);
}

View File

@@ -0,0 +1,24 @@
//===- Utils.h - llvm-reduce utility functions ----------------------------===//
//
// 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 contains some utility functions supporting llvm-reduce.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_REDUCE_DELTAS_UTILS_H
#define LLVM_TOOLS_LLVM_REDUCE_DELTAS_UTILS_H
#include "llvm/IR/Value.h"
namespace llvm {
Value *getDefaultValue(Type *T);
} // namespace llvm
#endif