diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -393,14 +393,26 @@ // If the FP induction variable still has uses, this is because something else // in the loop uses its value. In order to canonicalize the induction // variable, we chose to eliminate the IV and rewrite it in terms of an - // int->fp cast. + // int->fp cast. fp->int casts of the original induction can be directly + // simplified to use the integer induction . // // We give preference to sitofp over uitofp because it is faster on most // platforms. if (WeakPH) { - Value *Conv = new SIToFPInst(NewPHI, PN->getType(), "indvar.conv", - &*PN->getParent()->getFirstInsertionPt()); - PN->replaceAllUsesWith(Conv); + Value *Conv = nullptr; + for (Use &U : make_early_inc_range(PN->uses())) { + auto *FPToSI = dyn_cast(U.getUser()); + if (FPToSI && FPToSI->getType() == NewPHI->getType()) { + FPToSI->replaceAllUsesWith(NewPHI); + DeadInsts.push_back(FPToSI); + continue; + } + if (!Conv) + Conv = new SIToFPInst(NewPHI, PN->getType(), "indvar.conv", + &*PN->getParent()->getFirstInsertionPt()); + U.set(Conv); + } + RecursivelyDeleteTriviallyDeadInstructions(PN, TLI, MSSAU.get()); } return true; diff --git a/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll b/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll --- a/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll +++ b/llvm/test/Transforms/IndVarSimplify/floating-point-iv.ll @@ -382,8 +382,7 @@ ; CHECK-NEXT: [[FLOAT_IV_INT:%.*]] = phi i32 [ 1000, [[ENTRY:%.*]] ], [ [[FLOAT_IV_NEXT_INT:%.*]], [[LOOP]] ] ; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[FLOAT_IV_INT]] to float ; CHECK-NEXT: call void @use.float(float [[INDVAR_CONV]]) -; CHECK-NEXT: [[CONV_I32:%.*]] = fptosi float [[INDVAR_CONV]] to i32 -; CHECK-NEXT: call void @use.i32(i32 [[CONV_I32]]) +; CHECK-NEXT: call void @use.i32(i32 [[FLOAT_IV_INT]]) ; CHECK-NEXT: [[CONV_I16:%.*]] = fptosi float [[INDVAR_CONV]] to i16 ; CHECK-NEXT: [[CONV_I64:%.*]] = fptosi float [[INDVAR_CONV]] to i64 ; CHECK-NEXT: call void @use.i16(i16 [[CONV_I16]])