[llvm] b1b7fb6 - [InstCombine] trunc (fptoui|fptosi)
Samuel Parker via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 24 01:16:33 PST 2023
Author: Samuel Parker
Date: 2023-01-24T09:16:25Z
New Revision: b1b7fb6f20b056a7eb5731a98485f9d541c7aabe
URL: https://github.com/llvm/llvm-project/commit/b1b7fb6f20b056a7eb5731a98485f9d541c7aabe
DIFF: https://github.com/llvm/llvm-project/commit/b1b7fb6f20b056a7eb5731a98485f9d541c7aabe.diff
LOG: [InstCombine] trunc (fptoui|fptosi)
Attempt to fold the trunc into the fp-to-int conversion.
Differential Revision: https://reviews.llvm.org/D142093
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 23de923304358..cf84ca13f4e4f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -247,6 +247,11 @@ Value *InstCombinerImpl::EvaluateInDifferentType(Value *V, Type *Ty,
Res = NPN;
break;
}
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ Res = CastInst::Create(
+ static_cast<Instruction::CastOps>(Opc), I->getOperand(0), Ty);
+ break;
default:
// TODO: Can handle more cases here.
llvm_unreachable("Unreachable!");
@@ -491,6 +496,22 @@ static bool canEvaluateTruncated(Value *V, Type *Ty, InstCombinerImpl &IC,
return false;
return true;
}
+ case Instruction::FPToUI:
+ case Instruction::FPToSI: {
+ // If the integer type can hold the max FP value, it is safe to cast
+ // directly to that type. Otherwise, we may create poison via overflow
+ // that did not exist in the original code.
+ //
+ // The max FP value is pow(2, MaxExponent) * (1 + MaxFraction), so we need
+ // at least one more bit than the MaxExponent to hold the max FP value.
+ Type *InputTy = I->getOperand(0)->getType()->getScalarType();
+ const fltSemantics &Semantics = InputTy->getFltSemantics();
+ uint32_t MinBitWidth = APFloatBase::semanticsMaxExponent(Semantics);
+ // Extra sign bit needed.
+ if (I->getOpcode() == Instruction::FPToSI)
+ ++MinBitWidth;
+ return Ty->getScalarSizeInBits() > MinBitWidth;
+ }
default:
// TODO: Can handle more cases here.
break;
diff --git a/llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll b/llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll
index b287207ef5cf8..33e49fda38fe1 100644
--- a/llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll
+++ b/llvm/test/Transforms/InstCombine/trunc-fp-to-int.ll
@@ -7,9 +7,8 @@
define i16 @half_fptoui_i17_i16(half %x) {
; CHECK-LABEL: @half_fptoui_i17_i16(
-; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i17
-; CHECK-NEXT: [[R:%.*]] = trunc i17 [[I]] to i16
-; CHECK-NEXT: ret i16 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i16
+; CHECK-NEXT: ret i16 [[I]]
;
%i = fptoui half %x to i17
%r = trunc i17 %i to i16
@@ -33,9 +32,8 @@ define i15 @half_fptoui_i17_i15(half %x) {
define i16 @half_fptoui_i32_i16(half %x) {
; CHECK-LABEL: @half_fptoui_i32_i16(
-; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i32
-; CHECK-NEXT: [[R:%.*]] = trunc i32 [[I]] to i16
-; CHECK-NEXT: ret i16 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptoui half [[X:%.*]] to i16
+; CHECK-NEXT: ret i16 [[I]]
;
%i = fptoui half %x to i32
%r = trunc i32 %i to i16
@@ -60,9 +58,8 @@ define i17 @half_fptoui_i32_i17(half %x) {
define <4 x i16> @half_fptoui_4xi32_4xi16(<4 x half> %x) {
; CHECK-LABEL: @half_fptoui_4xi32_4xi16(
-; CHECK-NEXT: [[I:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i32>
-; CHECK-NEXT: [[R:%.*]] = trunc <4 x i32> [[I]] to <4 x i16>
-; CHECK-NEXT: ret <4 x i16> [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptoui <4 x half> [[X:%.*]] to <4 x i16>
+; CHECK-NEXT: ret <4 x i16> [[I]]
;
%i = fptoui <4 x half> %x to <4 x i32>
%r = trunc <4 x i32> %i to <4 x i16>
@@ -71,9 +68,8 @@ define <4 x i16> @half_fptoui_4xi32_4xi16(<4 x half> %x) {
define i128 @bfloat_fptoui_i129_i128(bfloat %x) {
; CHECK-LABEL: @bfloat_fptoui_i129_i128(
-; CHECK-NEXT: [[I:%.*]] = fptoui bfloat [[X:%.*]] to i129
-; CHECK-NEXT: [[R:%.*]] = trunc i129 [[I]] to i128
-; CHECK-NEXT: ret i128 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptoui bfloat [[X:%.*]] to i128
+; CHECK-NEXT: ret i128 [[I]]
;
%i = fptoui bfloat %x to i129
%r = trunc i129 %i to i128
@@ -95,9 +91,8 @@ define i127 @bfloat_fptoui_i128_i127(bfloat %x) {
define i128 @float_fptoui_i129_i128(float %x) {
; CHECK-LABEL: @float_fptoui_i129_i128(
-; CHECK-NEXT: [[I:%.*]] = fptoui float [[X:%.*]] to i129
-; CHECK-NEXT: [[R:%.*]] = trunc i129 [[I]] to i128
-; CHECK-NEXT: ret i128 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptoui float [[X:%.*]] to i128
+; CHECK-NEXT: ret i128 [[I]]
;
%i = fptoui float %x to i129
%r = trunc i129 %i to i128
@@ -134,9 +129,8 @@ define i127 @float_fptoui_i128_i127(float %x) {
define i1024 @double_fptoui_i1025_i1024(double %x) {
; CHECK-LABEL: @double_fptoui_i1025_i1024(
-; CHECK-NEXT: [[I:%.*]] = fptoui double [[X:%.*]] to i1025
-; CHECK-NEXT: [[R:%.*]] = trunc i1025 [[I]] to i1024
-; CHECK-NEXT: ret i1024 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptoui double [[X:%.*]] to i1024
+; CHECK-NEXT: ret i1024 [[I]]
;
%i = fptoui double %x to i1025
%r = trunc i1025 %i to i1024
@@ -171,9 +165,8 @@ define i16 @half_fptosi_i17_i16(half %x) {
define i17 @half_fptosi_i18_i17(half %x) {
; CHECK-LABEL: @half_fptosi_i18_i17(
-; CHECK-NEXT: [[I:%.*]] = fptosi half [[X:%.*]] to i18
-; CHECK-NEXT: [[R:%.*]] = trunc i18 [[I]] to i17
-; CHECK-NEXT: ret i17 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptosi half [[X:%.*]] to i17
+; CHECK-NEXT: ret i17 [[I]]
;
%i = fptosi half %x to i18
%r = trunc i18 %i to i17
@@ -212,9 +205,8 @@ define i18 @half_fptosi_i32_i18(half %x) {
define <4 x i17> @half_fptosi_4xi32_4xi17(<4 x half> %x) {
; CHECK-LABEL: @half_fptosi_4xi32_4xi17(
-; CHECK-NEXT: [[I:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i32>
-; CHECK-NEXT: [[R:%.*]] = trunc <4 x i32> [[I]] to <4 x i17>
-; CHECK-NEXT: ret <4 x i17> [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptosi <4 x half> [[X:%.*]] to <4 x i17>
+; CHECK-NEXT: ret <4 x i17> [[I]]
;
%i = fptosi <4 x half> %x to <4 x i32>
%r = trunc <4 x i32> %i to <4 x i17>
@@ -236,9 +228,8 @@ define i128 @bfloat_fptosi_i129_i128(bfloat %x) {
define i129 @bfloat_fptosi_i130_i129(bfloat %x) {
; CHECK-LABEL: @bfloat_fptosi_i130_i129(
-; CHECK-NEXT: [[I:%.*]] = fptosi bfloat [[X:%.*]] to i130
-; CHECK-NEXT: [[R:%.*]] = trunc i130 [[I]] to i129
-; CHECK-NEXT: ret i129 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptosi bfloat [[X:%.*]] to i129
+; CHECK-NEXT: ret i129 [[I]]
;
%i = fptosi bfloat %x to i130
%r = trunc i130 %i to i129
@@ -247,9 +238,8 @@ define i129 @bfloat_fptosi_i130_i129(bfloat %x) {
define i129 @float_fptosi_i130_i129(float %x) {
; CHECK-LABEL: @float_fptosi_i130_i129(
-; CHECK-NEXT: [[I:%.*]] = fptosi float [[X:%.*]] to i130
-; CHECK-NEXT: [[R:%.*]] = trunc i130 [[I]] to i129
-; CHECK-NEXT: ret i129 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptosi float [[X:%.*]] to i129
+; CHECK-NEXT: ret i129 [[I]]
;
%i = fptosi float %x to i130
%r = trunc i130 %i to i129
@@ -271,9 +261,8 @@ define i128 @float_fptosi_i129_i128(float %x) {
define i1025 @double_fptosi_i1026_i1025(double %x) {
; CHECK-LABEL: @double_fptosi_i1026_i1025(
-; CHECK-NEXT: [[I:%.*]] = fptosi double [[X:%.*]] to i1026
-; CHECK-NEXT: [[R:%.*]] = trunc i1026 [[I]] to i1025
-; CHECK-NEXT: ret i1025 [[R]]
+; CHECK-NEXT: [[I:%.*]] = fptosi double [[X:%.*]] to i1025
+; CHECK-NEXT: ret i1025 [[I]]
;
%i = fptosi double %x to i1026
%r = trunc i1026 %i to i1025
More information about the llvm-commits
mailing list