Index: llvm/lib/Transforms/Utils/SimplifyIndVar.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyIndVar.cpp +++ llvm/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -676,7 +676,8 @@ /// Eliminate redundant type cast between integer and float. bool SimplifyIndvar::replaceFloatIVWithIntegerIV(Instruction *UseInst) { - if (UseInst->getOpcode() != CastInst::SIToFP) + if (UseInst->getOpcode() != CastInst::SIToFP && + UseInst->getOpcode() != CastInst::UIToFP) return false; Value *IVOperand = UseInst->getOperand(0); Index: llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll =================================================================== --- llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll +++ llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll @@ -179,3 +179,70 @@ cleanup: ; preds = %for.body ret void } + +; https://godbolt.org/z/51MrqYjEf +define void @uitofp_fptoui_range () { +; CHECK-LABEL: @uitofp_fptoui_range( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[DEC_INT:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[IDXPROM:%.*]] = zext i32 [[IV_INT]] to i64 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 [[IDXPROM]] +; CHECK-NEXT: store i32 [[IV_INT]], i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 3 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP:%.*]] +; CHECK: cleanup: +; CHECK-NEXT: ret void +; +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %iv.int = phi i32 [ 100, %entry ], [ %dec.int, %for.body ] + %indvar.conv = uitofp i32 %iv.int to float + %conv = fptoui float %indvar.conv to i32 + %idxprom = zext i32 %conv to i64 + %arrayidx = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 %idxprom + store i32 %conv, i32* %arrayidx, align 4 + %dec.int = add nsw i32 %iv.int, -1 + %cmp = icmp ugt i32 %dec.int, 3 + br i1 %cmp, label %for.body, label %cleanup + +cleanup: ; preds = %for.body + ret void +} + +define void @uitofp_fptosi_range () { +; CHECK-LABEL: @uitofp_fptosi_range( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[DEC_INT:%.*]], [[FOR_BODY]] ] +; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[IV_INT]] to i64 +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 [[IDXPROM]] +; CHECK-NEXT: store i32 [[IV_INT]], i32* [[ARRAYIDX]], align 4 +; CHECK-NEXT: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 +; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 3 +; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP:%.*]] +; CHECK: cleanup: +; CHECK-NEXT: ret void +; +entry: + br label %for.body + +for.body: ; preds = %for.body, %entry + %iv.int = phi i32 [ 100, %entry ], [ %dec.int, %for.body ] + %indvar.conv = uitofp i32 %iv.int to float + %conv = fptosi float %indvar.conv to i32 + %idxprom = sext i32 %conv to i64 + %arrayidx = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 %idxprom + store i32 %conv, i32* %arrayidx, align 4 + %dec.int = add nsw i32 %iv.int, -1 + %cmp = icmp ugt i32 %dec.int, 3 + br i1 %cmp, label %for.body, label %cleanup + +cleanup: ; preds = %for.body + ret void +}