InstCombine: Fix infinite loop caused by visitFPTrunc
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 14 Nov 2014 21:21:15 +0000 (21:21 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 14 Nov 2014 21:21:15 +0000 (21:21 +0000)
We would attempt to replace a fptrunc of an frem with an identical
fptrunc.  This would cause the new fptrunc to be added to the worklist.
Of course, this results in an infinite loop because we will keep
visiting the newly created fptruncs.

This fixes PR21576.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222040 91177308-0d34-0410-b5e6-96231b3b80d8

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

index b41cdc65202f6dc6edbc00765a58b0c7dea9785b..a0570f7ebd474d5d61b4afcc1a7f7598dec8465d 100644 (file)
@@ -1269,14 +1269,17 @@ 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.
+        Value *NewLHS = LHSOrig, *NewRHS = RHSOrig;
         if (LHSWidth < SrcWidth)
-          LHSOrig = Builder->CreateFPExt(LHSOrig, RHSOrig->getType());
+          NewLHS = Builder->CreateFPExt(NewLHS, RHSOrig->getType());
         else if (RHSWidth <= SrcWidth)
-          RHSOrig = Builder->CreateFPExt(RHSOrig, LHSOrig->getType());
-        Value *ExactResult = Builder->CreateFRem(LHSOrig, RHSOrig);
-        if (Instruction *RI = dyn_cast<Instruction>(ExactResult))
-          RI->copyFastMathFlags(OpI);
-        return CastInst::CreateFPCast(ExactResult, CI.getType());
+          NewRHS = Builder->CreateFPExt(NewRHS, LHSOrig->getType());
+        if (NewLHS != LHSOrig || NewRHS != RHSOrig) {
+          Value *ExactResult = Builder->CreateFRem(NewLHS, NewRHS);
+          if (Instruction *RI = dyn_cast<Instruction>(ExactResult))
+            RI->copyFastMathFlags(OpI);
+          return CastInst::CreateFPCast(ExactResult, CI.getType());
+        }
     }
 
     // (fptrunc (fneg x)) -> (fneg (fptrunc x))
index 9be66fd42c68d75a1d03cd6e478a078431a9daf0..c4c8578198b557f2a04ff986e390ca324e7f463b 100644 (file)
@@ -53,3 +53,13 @@ define half @test5(float %a, float %b, float %c) {
 }
 
 declare float @llvm.fabs.f32(float) nounwind readonly
+
+define <1 x float> @test6(<1 x double> %V) {
+  %frem = frem <1 x double> %V, %V
+  %trunc = fptrunc <1 x double> %frem to <1 x float>
+  ret <1 x float> %trunc
+; CHECK-LABEL: @test6
+; CHECK-NEXT: %[[frem:.*]]  = frem <1 x double> %V, %V
+; CHECK-NEXT: %[[trunc:.*]] = fptrunc <1 x double> %[[frem]] to <1 x float>
+; CHECK-NEXT: ret <1 x float> %trunc
+}