Fix another infinite loop in InstCombine
authorSteven Wu <stevenwu@apple.com>
Fri, 12 Dec 2014 04:34:07 +0000 (04:34 +0000)
committerSteven Wu <stevenwu@apple.com>
Fri, 12 Dec 2014 04:34:07 +0000 (04:34 +0000)
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

lib/Transforms/InstCombine/InstCombineCasts.cpp
test/Transforms/InstCombine/fpcast.ll

index aba77bb44625cb67c1afa7683571d3b447c8b16f..357bf24ebe2ee4443916065ac37a318be601039e 100644 (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))
index ac034028b22d6938a9763728c424393fa4d434e4..8319624b87c9d00932b90c1cfb1ebbac8e95c37c 100644 (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
+}