Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[IndVars] Eliminate redundant type cast between integer and float
Recompute the range: match for fptosi of sitofp, and then query the range of the input to the sitofp according the comment on D129140. Fixes #55505. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D129191
- Loading branch information
Showing
3 changed files
with
150 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
llvm/test/Transforms/IndVarSimplify/floating-point-small-iv.ll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | ||
; RUN: opt < %s -indvars -S | FileCheck %s | ||
|
||
@array = dso_local global [16777219 x i32] zeroinitializer, align 4 | ||
|
||
define void @small_const_bound(i32 %index) { | ||
; CHECK-LABEL: @small_const_bound( | ||
; 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]], 0 | ||
; 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 = sitofp 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, 0 | ||
br i1 %cmp, label %for.body, label %cleanup | ||
|
||
cleanup: ; preds = %for.body | ||
ret void | ||
} | ||
|
||
; Negative test: The transform is *not* valid because there are too many significant bits | ||
define void @overflow_masked_const_bound(i32 %index) { | ||
; CHECK-LABEL: @overflow_masked_const_bound( | ||
; CHECK-NEXT: entry: | ||
; CHECK-NEXT: br label [[FOR_BODY:%.*]] | ||
; CHECK: for.body: | ||
; CHECK-NEXT: [[IV_INT:%.*]] = phi i32 [ 16777218, [[ENTRY:%.*]] ], [ [[DEC_INT:%.*]], [[FOR_BODY]] ] | ||
; CHECK-NEXT: [[INDVAR_CONV:%.*]] = sitofp i32 [[IV_INT]] to float | ||
; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[INDVAR_CONV]] to i32 | ||
; CHECK-NEXT: [[IDXPROM:%.*]] = sext i32 [[CONV]] 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: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 | ||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 0 | ||
; 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 [ 16777218, %entry ], [ %dec.int, %for.body ] ; intermediate 16777218 (= 1 << 24 + 2) | ||
%indvar.conv = sitofp 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, 0 | ||
br i1 %cmp, label %for.body, label %cleanup | ||
|
||
cleanup: ; preds = %for.body | ||
ret void | ||
} | ||
|
||
; Negative test: Type mismatch between the integer IV and the fptosi result | ||
define void @mismatch_type_const(i32 %index) { | ||
; | ||
; CHECK-LABEL: @mismatch_type_const( | ||
; 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:%.*]] = fptosi float [[INDVAR_CONV]] to i16 | ||
; CHECK-NEXT: [[IDXPROM32:%.*]] = sext i16 [[CONV]] to i32 | ||
; CHECK-NEXT: [[IDXPROM64:%.*]] = sext i16 [[CONV]] to i64 | ||
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 [[IDXPROM64]] | ||
; CHECK-NEXT: store i32 [[IDXPROM32]], i32* [[ARRAYIDX]], align 4 | ||
; CHECK-NEXT: [[DEC_INT]] = add nsw i32 [[IV_INT]], -1 | ||
; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[DEC_INT]], 0 | ||
; 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 = sitofp i32 %iv.int to float | ||
%conv = fptosi float %indvar.conv to i16 | ||
%idxprom32 = sext i16 %conv to i32 | ||
%idxprom64 = sext i16 %conv to i64 | ||
%arrayidx = getelementptr inbounds [16777219 x i32], [16777219 x i32]* @array, i64 0, i64 %idxprom64 | ||
store i32 %idxprom32, i32* %arrayidx, align 4 | ||
%dec.int = add nsw i32 %iv.int, -1 | ||
%cmp = icmp ugt i32 %dec.int, 0 | ||
br i1 %cmp, label %for.body, label %cleanup | ||
|
||
cleanup: ; preds = %for.body | ||
ret void | ||
} |