[llvm] r222040 - InstCombine: Fix infinite loop caused by visitFPTrunc

David Majnemer david.majnemer at gmail.com
Fri Nov 14 13:21:16 PST 2014


Author: majnemer
Date: Fri Nov 14 15:21:15 2014
New Revision: 222040

URL: http://llvm.org/viewvc/llvm-project?rev=222040&view=rev
Log:
InstCombine: Fix infinite loop caused by visitFPTrunc

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.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/test/Transforms/InstCombine/fpcast.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=222040&r1=222039&r2=222040&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Fri Nov 14 15:21:15 2014
@@ -1269,14 +1269,17 @@ Instruction *InstCombiner::visitFPTrunc(
         // 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))

Modified: llvm/trunk/test/Transforms/InstCombine/fpcast.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/fpcast.ll?rev=222040&r1=222039&r2=222040&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/fpcast.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/fpcast.ll Fri Nov 14 15:21:15 2014
@@ -53,3 +53,13 @@ define half @test5(float %a, float %b, f
 }
 
 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
+}





More information about the llvm-commits mailing list