[llvm] 3a6b766 - [IndVars] Directly use unsigned integer induction for FPToUI/FPToSI of float induction

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 16 19:51:21 PDT 2022


Author: zhongyunde
Date: 2022-07-17T10:48:35+08:00
New Revision: 3a6b766b1b8211790529aab6358f1224f0b864c1

URL: https://github.com/llvm/llvm-project/commit/3a6b766b1b8211790529aab6358f1224f0b864c1
DIFF: https://github.com/llvm/llvm-project/commit/3a6b766b1b8211790529aab6358f1224f0b864c1.diff

LOG: [IndVars] Directly use unsigned integer induction for FPToUI/FPToSI of float induction

Depend on D129358

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D129756

Added: 
    

Modified: 
    llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
    llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
index ded383de892ea..dfc0de54d67f3 100644
--- a/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyIndVar.cpp
@@ -679,14 +679,20 @@ bool SimplifyIndvar::replaceIVUserWithLoopInvariant(Instruction *I) {
 
 /// 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);
   // Get the symbolic expression for this instruction.
-  ConstantRange IVRange = SE->getSignedRange(SE->getSCEV(IVOperand));
+  const SCEV *IV = SE->getSCEV(IVOperand);
+  unsigned MaskBits;
+  if (UseInst->getOpcode() == CastInst::SIToFP)
+    MaskBits = SE->getSignedRange(IV).getMinSignedBits();
+  else
+    MaskBits = SE->getUnsignedRange(IV).getActiveBits();
   unsigned DestNumSigBits = UseInst->getType()->getFPMantissaWidth();
-  if (IVRange.getActiveBits() <= DestNumSigBits) {
+  if (MaskBits <= DestNumSigBits) {
     for (User *U : UseInst->users()) {
       // Match for fptosi/fptoui of sitofp and with same type.
       auto *CI = dyn_cast<CastInst>(U);

diff  --git a/llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll b/llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll
index 546103161fdde..9795b48b881ac 100644
--- a/llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll
+++ b/llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll
@@ -3,8 +3,8 @@
 
 @array = dso_local global [16777219 x i32] zeroinitializer, align 4
 
-define void @small_const_bound() {
-; CHECK-LABEL: @small_const_bound(
+define void @sitofp_fptosi_range() {
+; CHECK-LABEL: @sitofp_fptosi_range(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
@@ -37,8 +37,8 @@ cleanup:                                          ; preds = %for.body
 }
 
 ; Negative test: The transform is *not* valid because there are too many significant bits
-define void @overflow_masked_const_bound() {
-; CHECK-LABEL: @overflow_masked_const_bound(
+define void @sitofp_fptosi_range_overflow() {
+; CHECK-LABEL: @sitofp_fptosi_range_overflow(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
@@ -73,9 +73,9 @@ cleanup:                                          ; preds = %for.body
 }
 
 ; Negative test: Type mismatch between the integer IV and the fptosi result
-define void @mismatch_type_const() {
+define void @sitofp_fptosi_range_mismatch_type() {
 ;
-; CHECK-LABEL: @mismatch_type_const(
+; CHECK-LABEL: @sitofp_fptosi_range_mismatch_type(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
@@ -111,8 +111,8 @@ cleanup:                                          ; preds = %for.body
   ret void
 }
 
-define void @unsigned_const_bound() {
-; CHECK-LABEL: @unsigned_const_bound(
+define void @sitofp_fptoui_range() {
+; CHECK-LABEL: @sitofp_fptoui_range(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
 ; CHECK:       for.body:
@@ -144,18 +144,16 @@ cleanup:                                          ; preds = %for.body
   ret void
 }
 
-; TODO: Range including negative value.
-define void @unsigned_const_bound_with_negative () {
-; CHECK-LABEL: @unsigned_const_bound_with_negative(
+; Range including negative value.
+define void @sitofp_fptoui_range_with_negative () {
+; CHECK-LABEL: @sitofp_fptoui_range_with_negative(
 ; 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:    [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to float
-; CHECK-NEXT:    [[CONV:%.*]] = fptoui float [[INDVAR_CONV]] to i32
-; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[CONV]] to i64
+; 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 [[CONV]], i32* [[ARRAYIDX]], align 4
+; CHECK-NEXT:    store i32 [[IV_INT]], i32* [[ARRAYIDX]], align 4
 ; CHECK-NEXT:    [[DEC_INT]] = add nsw i32 [[IV_INT]], -1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[DEC_INT]], -100
 ; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[CLEANUP:%.*]]
@@ -179,3 +177,127 @@ for.body:                                         ; preds = %for.body, %entry
 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_fptoui_range_with_negative() {
+; CHECK-LABEL: @uitofp_fptoui_range_with_negative(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    store i32 100, i32* getelementptr inbounds ([16777219 x i32], [16777219 x i32]* @array, i64 0, i64 100), align 4
+; CHECK-NEXT:    br i1 false, 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, -100
+  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
+}
+
+define void @uitofp_fptosi_range_with_negative () {
+; CHECK-LABEL: @uitofp_fptosi_range_with_negative(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    store i32 100, i32* getelementptr inbounds ([16777219 x i32], [16777219 x i32]* @array, i64 0, i64 100), align 4
+; CHECK-NEXT:    br i1 false, 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, -100
+  br i1 %cmp, label %for.body, label %cleanup
+
+cleanup:                                          ; preds = %for.body
+  ret void
+}
+


        


More information about the llvm-commits mailing list