mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[Float2Int] avoid crashing on unreachable code (PR38502)
In the example from: https://bugs.llvm.org/show_bug.cgi?id=38502 ...we hit infinite looping/crashing because we have non-standard IR - an instruction operand is used before defined. This and other unusual constructs are allowed in unreachable blocks, so avoid the problem by using DominatorTree to step around landmines. Differential Revision: https://reviews.llvm.org/D67766 llvm-svn: 372339
This commit is contained in:
parent
c204981f6f
commit
c86655e22d
@ -17,6 +17,7 @@
|
||||
#include "llvm/ADT/EquivalenceClasses.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "llvm/IR/ConstantRange.h"
|
||||
#include "llvm/IR/Dominators.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
|
||||
@ -26,10 +27,11 @@ public:
|
||||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
|
||||
|
||||
// Glue for old PM.
|
||||
bool runImpl(Function &F);
|
||||
bool runImpl(Function &F, const DominatorTree &DT);
|
||||
|
||||
private:
|
||||
void findRoots(Function &F, SmallPtrSet<Instruction *, 8> &Roots);
|
||||
void findRoots(Function &F, const DominatorTree &DT,
|
||||
SmallPtrSet<Instruction *, 8> &Roots);
|
||||
void seen(Instruction *I, ConstantRange R);
|
||||
ConstantRange badRange();
|
||||
ConstantRange unknownRange();
|
||||
|
@ -60,11 +60,13 @@ namespace {
|
||||
if (skipFunction(F))
|
||||
return false;
|
||||
|
||||
return Impl.runImpl(F);
|
||||
const DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
||||
return Impl.runImpl(F, DT);
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<DominatorTreeWrapperPass>();
|
||||
AU.addPreserved<GlobalsAAWrapperPass>();
|
||||
}
|
||||
|
||||
@ -116,21 +118,29 @@ static Instruction::BinaryOps mapBinOpcode(unsigned Opcode) {
|
||||
|
||||
// Find the roots - instructions that convert from the FP domain to
|
||||
// integer domain.
|
||||
void Float2IntPass::findRoots(Function &F, SmallPtrSet<Instruction*,8> &Roots) {
|
||||
for (auto &I : instructions(F)) {
|
||||
if (isa<VectorType>(I.getType()))
|
||||
void Float2IntPass::findRoots(Function &F, const DominatorTree &DT,
|
||||
SmallPtrSet<Instruction*,8> &Roots) {
|
||||
for (BasicBlock &BB : F) {
|
||||
// Unreachable code can take on strange forms that we are not prepared to
|
||||
// handle. For example, an instruction may have itself as an operand.
|
||||
if (!DT.isReachableFromEntry(&BB))
|
||||
continue;
|
||||
switch (I.getOpcode()) {
|
||||
default: break;
|
||||
case Instruction::FPToUI:
|
||||
case Instruction::FPToSI:
|
||||
Roots.insert(&I);
|
||||
break;
|
||||
case Instruction::FCmp:
|
||||
if (mapFCmpPred(cast<CmpInst>(&I)->getPredicate()) !=
|
||||
CmpInst::BAD_ICMP_PREDICATE)
|
||||
|
||||
for (Instruction &I : BB) {
|
||||
if (isa<VectorType>(I.getType()))
|
||||
continue;
|
||||
switch (I.getOpcode()) {
|
||||
default: break;
|
||||
case Instruction::FPToUI:
|
||||
case Instruction::FPToSI:
|
||||
Roots.insert(&I);
|
||||
break;
|
||||
break;
|
||||
case Instruction::FCmp:
|
||||
if (mapFCmpPred(cast<CmpInst>(&I)->getPredicate()) !=
|
||||
CmpInst::BAD_ICMP_PREDICATE)
|
||||
Roots.insert(&I);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -503,7 +513,7 @@ void Float2IntPass::cleanup() {
|
||||
I.first->eraseFromParent();
|
||||
}
|
||||
|
||||
bool Float2IntPass::runImpl(Function &F) {
|
||||
bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {
|
||||
LLVM_DEBUG(dbgs() << "F2I: Looking at function " << F.getName() << "\n");
|
||||
// Clear out all state.
|
||||
ECs = EquivalenceClasses<Instruction*>();
|
||||
@ -513,7 +523,7 @@ bool Float2IntPass::runImpl(Function &F) {
|
||||
|
||||
Ctx = &F.getParent()->getContext();
|
||||
|
||||
findRoots(F, Roots);
|
||||
findRoots(F, DT, Roots);
|
||||
|
||||
walkBackwards(Roots);
|
||||
walkForwards();
|
||||
@ -527,8 +537,9 @@ bool Float2IntPass::runImpl(Function &F) {
|
||||
namespace llvm {
|
||||
FunctionPass *createFloat2IntPass() { return new Float2IntLegacyPass(); }
|
||||
|
||||
PreservedAnalyses Float2IntPass::run(Function &F, FunctionAnalysisManager &) {
|
||||
if (!runImpl(F))
|
||||
PreservedAnalyses Float2IntPass::run(Function &F, FunctionAnalysisManager &AM) {
|
||||
const DominatorTree &DT = AM.getResult<DominatorTreeAnalysis>(F);
|
||||
if (!runImpl(F, DT))
|
||||
return PreservedAnalyses::all();
|
||||
|
||||
PreservedAnalyses PA;
|
||||
|
@ -185,8 +185,8 @@
|
||||
; CHECK-NEXT: CallGraph Construction
|
||||
; CHECK-NEXT: Globals Alias Analysis
|
||||
; CHECK-NEXT: FunctionPass Manager
|
||||
; CHECK-NEXT: Float to int
|
||||
; CHECK-NEXT: Dominator Tree Construction
|
||||
; CHECK-NEXT: Float to int
|
||||
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
|
||||
; CHECK-NEXT: Function Alias Analysis Results
|
||||
; CHECK-NEXT: Memory SSA
|
||||
|
@ -190,8 +190,8 @@
|
||||
; CHECK-NEXT: CallGraph Construction
|
||||
; CHECK-NEXT: Globals Alias Analysis
|
||||
; CHECK-NEXT: FunctionPass Manager
|
||||
; CHECK-NEXT: Float to int
|
||||
; CHECK-NEXT: Dominator Tree Construction
|
||||
; CHECK-NEXT: Float to int
|
||||
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
|
||||
; CHECK-NEXT: Function Alias Analysis Results
|
||||
; CHECK-NEXT: Memory SSA
|
||||
|
@ -172,8 +172,8 @@
|
||||
; CHECK-NEXT: CallGraph Construction
|
||||
; CHECK-NEXT: Globals Alias Analysis
|
||||
; CHECK-NEXT: FunctionPass Manager
|
||||
; CHECK-NEXT: Float to int
|
||||
; CHECK-NEXT: Dominator Tree Construction
|
||||
; CHECK-NEXT: Float to int
|
||||
; CHECK-NEXT: Basic Alias Analysis (stateless AA impl)
|
||||
; CHECK-NEXT: Function Alias Analysis Results
|
||||
; CHECK-NEXT: Memory SSA
|
||||
|
@ -328,3 +328,25 @@ define <4 x i16> @neg_vector(<4 x i8> %a) {
|
||||
%t2 = fptoui <4 x float> %t1 to <4 x i16>
|
||||
ret <4 x i16> %t2
|
||||
}
|
||||
|
||||
; Don't crash while processing unreachable (non-standard) IR.
|
||||
|
||||
define void @PR38502() {
|
||||
; CHECK-LABEL: @PR38502(
|
||||
; CHECK-NEXT: entry:
|
||||
; CHECK-NEXT: ret void
|
||||
; CHECK: bogusBB:
|
||||
; CHECK-NEXT: [[INC1:%.*]] = fadd double [[INC:%.*]], 1.000000e+00
|
||||
; CHECK-NEXT: [[INC]] = fadd double [[INC1]], 1.000000e+00
|
||||
; CHECK-NEXT: [[TOBOOL:%.*]] = fcmp une double [[INC]], 0.000000e+00
|
||||
; CHECK-NEXT: br label [[BOGUSBB:%.*]]
|
||||
;
|
||||
entry:
|
||||
ret void
|
||||
|
||||
bogusBB: ; preds = %bogusBB
|
||||
%inc1 = fadd double %inc, 1.000000e+00
|
||||
%inc = fadd double %inc1, 1.000000e+00
|
||||
%tobool = fcmp une double %inc, 0.000000e+00
|
||||
br label %bogusBB
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user