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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224097 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steven Wu 2014-12-12 04:34:07 +00:00
parent 002ca4ca3f
commit a511846bdf
2 changed files with 24 additions and 9 deletions

View File

@ -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<Instruction>(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<Instruction>(ExactResult))
RI->copyFastMathFlags(OpI);
return CastInst::CreateFPCast(ExactResult, CI.getType());
}
}
break;
}
// (fptrunc (fneg x)) -> (fneg (fptrunc x))

View File

@ -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
}