stop llvm-reduce from introducing undefs
Differential Revision: https://reviews.llvm.org/D128317
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 * {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "Delta.h"
|
||||
|
||||
namespace llvm {
|
||||
void reduceOperandsUndefDeltaPass(TestRunner &Test);
|
||||
void reduceOperandsOneDeltaPass(TestRunner &Test);
|
||||
void reduceOperandsZeroDeltaPass(TestRunner &Test);
|
||||
} // namespace llvm
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
20
llvm/tools/llvm-reduce/deltas/Utils.cpp
Normal file
20
llvm/tools/llvm-reduce/deltas/Utils.cpp
Normal 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);
|
||||
}
|
||||
24
llvm/tools/llvm-reduce/deltas/Utils.h
Normal file
24
llvm/tools/llvm-reduce/deltas/Utils.h
Normal 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
|
||||
Reference in New Issue
Block a user