From 896d3dd47b4c47919cede14856bfe50e09c956bc Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Fri, 12 Dec 2014 04:34:07 +0000 Subject: [PATCH] Fix another infinite loop in InstCombine Summary: InstCombine infinite-loops for the testcase added It is because InstCombine is generating instructions that can be optimized by itself. Fix by not optimizing frem if the optimized type is the same as original type. rdar://problem/19150820 Reviewers: majnemer Differential Revision: http://reviews.llvm.org/D6634 llvm-svn: 224097 --- .../InstCombine/InstCombineCasts.cpp | 21 +++++++++++-------- test/Transforms/InstCombine/fpcast.ll | 12 +++++++++++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/InstCombine/InstCombineCasts.cpp b/lib/Transforms/InstCombine/InstCombineCasts.cpp index aba77bb4462..357bf24ebe2 100644 --- a/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1269,16 +1269,19 @@ Instruction *InstCombiner::visitFPTrunc(FPTruncInst &CI) { // type of OpI doesn't enter into things at all. We simply evaluate // in whichever source type is larger, then convert to the // destination type. - if (LHSWidth < SrcWidth) - LHSOrig = Builder->CreateFPExt(LHSOrig, RHSOrig->getType()); - else if (RHSWidth <= SrcWidth) - RHSOrig = Builder->CreateFPExt(RHSOrig, LHSOrig->getType()); - if (LHSOrig != OpI->getOperand(0) || RHSOrig != OpI->getOperand(1)) { - Value *ExactResult = Builder->CreateFRem(LHSOrig, RHSOrig); - if (Instruction *RI = dyn_cast(ExactResult)) - RI->copyFastMathFlags(OpI); - return CastInst::CreateFPCast(ExactResult, CI.getType()); + if (SrcWidth != OpWidth) { + if (LHSWidth < SrcWidth) + LHSOrig = Builder->CreateFPExt(LHSOrig, RHSOrig->getType()); + else if (RHSWidth <= SrcWidth) + RHSOrig = Builder->CreateFPExt(RHSOrig, LHSOrig->getType()); + if (LHSOrig != OpI->getOperand(0) || RHSOrig != OpI->getOperand(1)) { + Value *ExactResult = Builder->CreateFRem(LHSOrig, RHSOrig); + if (Instruction *RI = dyn_cast(ExactResult)) + RI->copyFastMathFlags(OpI); + return CastInst::CreateFPCast(ExactResult, CI.getType()); + } } + break; } // (fptrunc (fneg x)) -> (fneg (fptrunc x)) diff --git a/test/Transforms/InstCombine/fpcast.ll b/test/Transforms/InstCombine/fpcast.ll index ac034028b22..8319624b87c 100644 --- a/test/Transforms/InstCombine/fpcast.ll +++ b/test/Transforms/InstCombine/fpcast.ll @@ -73,3 +73,15 @@ define float @test7(double %V) { ; CHECK-NEXT: %[[trunc:.*]] = fptrunc double %frem to float ; CHECK-NEXT: ret float %trunc } + +define float @test8(float %V) { + %fext = fpext float %V to double + %frem = frem double %fext, 1.000000e-01 + %trunc = fptrunc double %frem to float + ret float %trunc +; CHECK-LABEL: @test8 +; CHECK-NEXT: %[[fext:.*]] = fpext float %V to double +; CHECK-NEXT: %[[frem:.*]] = frem double %fext, 1.000000e-01 +; CHECK-NEXT: %[[trunc:.*]] = fptrunc double %frem to float +; CHECK-NEXT: ret float %trunc +}