Index: llvm/trunk/include/llvm/Transforms/Scalar/Float2Int.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar/Float2Int.h +++ llvm/trunk/include/llvm/Transforms/Scalar/Float2Int.h @@ -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 @@ 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 &Roots); + void findRoots(Function &F, const DominatorTree &DT, + SmallPtrSet &Roots); void seen(Instruction *I, ConstantRange R); ConstantRange badRange(); ConstantRange unknownRange(); Index: llvm/trunk/lib/Transforms/Scalar/Float2Int.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/Float2Int.cpp +++ llvm/trunk/lib/Transforms/Scalar/Float2Int.cpp @@ -60,11 +60,13 @@ if (skipFunction(F)) return false; - return Impl.runImpl(F); + const DominatorTree &DT = getAnalysis().getDomTree(); + return Impl.runImpl(F, DT); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); + AU.addRequired(); AU.addPreserved(); } @@ -116,21 +118,29 @@ // Find the roots - instructions that convert from the FP domain to // integer domain. -void Float2IntPass::findRoots(Function &F, SmallPtrSet &Roots) { - for (auto &I : instructions(F)) { - if (isa(I.getType())) +void Float2IntPass::findRoots(Function &F, const DominatorTree &DT, + SmallPtrSet &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(&I)->getPredicate()) != - CmpInst::BAD_ICMP_PREDICATE) + + for (Instruction &I : BB) { + if (isa(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(&I)->getPredicate()) != + CmpInst::BAD_ICMP_PREDICATE) + Roots.insert(&I); + break; + } } } } @@ -503,7 +513,7 @@ 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(); @@ -513,7 +523,7 @@ Ctx = &F.getParent()->getContext(); - findRoots(F, Roots); + findRoots(F, DT, Roots); walkBackwards(Roots); walkForwards(); @@ -527,8 +537,9 @@ 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(F); + if (!runImpl(F, DT)) return PreservedAnalyses::all(); PreservedAnalyses PA; Index: llvm/trunk/test/Other/opt-O2-pipeline.ll =================================================================== --- llvm/trunk/test/Other/opt-O2-pipeline.ll +++ llvm/trunk/test/Other/opt-O2-pipeline.ll @@ -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 Index: llvm/trunk/test/Other/opt-O3-pipeline.ll =================================================================== --- llvm/trunk/test/Other/opt-O3-pipeline.ll +++ llvm/trunk/test/Other/opt-O3-pipeline.ll @@ -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 Index: llvm/trunk/test/Other/opt-Os-pipeline.ll =================================================================== --- llvm/trunk/test/Other/opt-Os-pipeline.ll +++ llvm/trunk/test/Other/opt-Os-pipeline.ll @@ -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 Index: llvm/trunk/test/Transforms/Float2Int/basic.ll =================================================================== --- llvm/trunk/test/Transforms/Float2Int/basic.ll +++ llvm/trunk/test/Transforms/Float2Int/basic.ll @@ -328,3 +328,25 @@ %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 +}