InstCombine: Fix another infinite loop caused by visitFPTrunc
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 18 Nov 2014 22:06:45 +0000 (22:06 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 18 Nov 2014 22:06:45 +0000 (22:06 +0000)
We would attempt to replace an frem's operand with the same operand.
This would cause InstCombine to think real work was done, causing
InstCombine to enter an infinite loop.

This fixes the second part of PR21576.

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

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

index a0570f7ebd474d5d61b4afcc1a7f7598dec8465d..aba77bb44625cb67c1afa7683571d3b447c8b16f 100644 (file)
@@ -1269,13 +1269,12 @@ 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)
-          NewLHS = Builder->CreateFPExt(NewLHS, RHSOrig->getType());
+          LHSOrig = Builder->CreateFPExt(LHSOrig, RHSOrig->getType());
         else if (RHSWidth <= SrcWidth)
-          NewRHS = Builder->CreateFPExt(NewRHS, LHSOrig->getType());
-        if (NewLHS != LHSOrig || NewRHS != RHSOrig) {
-          Value *ExactResult = Builder->CreateFRem(NewLHS, NewRHS);
+          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());
index c4c8578198b557f2a04ff986e390ca324e7f463b..ac034028b22d6938a9763728c424393fa4d434e4 100644 (file)
@@ -63,3 +63,13 @@ define <1 x float> @test6(<1 x double> %V) {
 ; CHECK-NEXT: %[[trunc:.*]] = fptrunc <1 x double> %[[frem]] to <1 x float>
 ; CHECK-NEXT: ret <1 x float> %trunc
 }
+
+define float @test7(double %V) {
+  %frem = frem double %V, 1.000000e+00
+  %trunc = fptrunc double %frem to float
+  ret float %trunc
+; CHECK-LABEL: @test7
+; CHECK-NEXT: %[[frem:.*]]  = frem double %V, 1.000000e+00
+; CHECK-NEXT: %[[trunc:.*]] = fptrunc double %frem to float
+; CHECK-NEXT: ret float %trunc
+}