[llvm] a62533c - [InstCombine] fold fpext into exact integer-to-FP cast
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun May 10 04:09:48 PDT 2020
Author: Sanjay Patel
Date: 2020-05-10T07:04:54-04:00
New Revision: a62533c29f842ba39c6e47a09b59bb0ae2dcc31b
URL: https://github.com/llvm/llvm-project/commit/a62533c29f842ba39c6e47a09b59bb0ae2dcc31b
DIFF: https://github.com/llvm/llvm-project/commit/a62533c29f842ba39c6e47a09b59bb0ae2dcc31b.diff
LOG: [InstCombine] fold fpext into exact integer-to-FP cast
We can combine a floating-point extension cast with a conversion
from integer if we know the earlier cast is exact.
This is an optimization suggested in PR36617:
https://bugs.llvm.org/show_bug.cgi?id=36617#c19
However, this patch does not change the example suggested there.
This patch only uses the existing analysis to handle cases where
the integer source value magnitude is narrower than the
intermediate FP mantissa (guarantees that the conversion to FP is
exact). Follow-up patches to the analysis function can enable
more cases.
Differential Revision: https://reviews.llvm.org/D79116
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
llvm/test/Transforms/InstCombine/fpextend.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 2bb314069121..c5b0956232b2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -1757,8 +1757,18 @@ static bool isKnownExactCastIntToFP(CastInst &I) {
return false;
}
-Instruction *InstCombiner::visitFPExt(CastInst &CI) {
- return commonCastTransforms(CI);
+Instruction *InstCombiner::visitFPExt(CastInst &FPExt) {
+ // If the source operand is a cast from integer to FP and known exact, then
+ // cast the integer operand directly to the destination type.
+ Type *Ty = FPExt.getType();
+ Value *Src = FPExt.getOperand(0);
+ if (isa<SIToFPInst>(Src) || isa<UIToFPInst>(Src)) {
+ auto *FPCast = cast<CastInst>(Src);
+ if (isKnownExactCastIntToFP(*FPCast))
+ return CastInst::Create(FPCast->getOpcode(), FPCast->getOperand(0), Ty);
+ }
+
+ return commonCastTransforms(FPExt);
}
/// fpto{s/u}i({u/s}itofp(X)) --> X or zext(X) or sext(X) or trunc(X)
diff --git a/llvm/test/Transforms/InstCombine/fpextend.ll b/llvm/test/Transforms/InstCombine/fpextend.ll
index 7125f305958d..1b6afd3216d7 100644
--- a/llvm/test/Transforms/InstCombine/fpextend.ll
+++ b/llvm/test/Transforms/InstCombine/fpextend.ll
@@ -259,10 +259,11 @@ define float @test18(half %x, half %y) nounwind {
ret float %t56
}
+; Convert from integer is exact, so convert directly to double.
+
define double @ItoFtoF_s25_f32_f64(i25 %i) {
; CHECK-LABEL: @ItoFtoF_s25_f32_f64(
-; CHECK-NEXT: [[X:%.*]] = sitofp i25 [[I:%.*]] to float
-; CHECK-NEXT: [[R:%.*]] = fpext float [[X]] to double
+; CHECK-NEXT: [[R:%.*]] = sitofp i25 [[I:%.*]] to double
; CHECK-NEXT: ret double [[R]]
;
%x = sitofp i25 %i to float
@@ -270,10 +271,11 @@ define double @ItoFtoF_s25_f32_f64(i25 %i) {
ret double %r
}
+; Convert from integer is exact, so convert directly to fp128.
+
define fp128 @ItoFtoF_u24_f32_f128(i24 %i) {
; CHECK-LABEL: @ItoFtoF_u24_f32_f128(
-; CHECK-NEXT: [[X:%.*]] = uitofp i24 [[I:%.*]] to float
-; CHECK-NEXT: [[R:%.*]] = fpext float [[X]] to fp128
+; CHECK-NEXT: [[R:%.*]] = uitofp i24 [[I:%.*]] to fp128
; CHECK-NEXT: ret fp128 [[R]]
;
%x = uitofp i24 %i to float
@@ -281,6 +283,8 @@ define fp128 @ItoFtoF_u24_f32_f128(i24 %i) {
ret fp128 %r
}
+; Negative test - intermediate rounding in float type.
+
define double @ItoFtoF_s26_f32_f64(i26 %i) {
; CHECK-LABEL: @ItoFtoF_s26_f32_f64(
; CHECK-NEXT: [[X:%.*]] = sitofp i26 [[I:%.*]] to float
@@ -292,6 +296,8 @@ define double @ItoFtoF_s26_f32_f64(i26 %i) {
ret double %r
}
+; Negative test - intermediate rounding in float type.
+
define double @ItoFtoF_u25_f32_f64(i25 %i) {
; CHECK-LABEL: @ItoFtoF_u25_f32_f64(
; CHECK-NEXT: [[X:%.*]] = uitofp i25 [[I:%.*]] to float
More information about the llvm-commits
mailing list