-
Notifications
You must be signed in to change notification settings - Fork 15.5k
Reapply "InstCombine: Fold ldexp with constant exponent to fmul" (#171895) #171977
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
@llvm/pr-subscribers-llvm-transforms Author: Matt Arsenault (arsenm) ChangesThis reverts commit 757c5b3. Reapply with the transform skipped if the scaling overflows or underflows. Full diff: https://github.com/llvm/llvm-project/pull/171977.diff 3 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 85602a5a7575a..04796807ea557 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3089,6 +3089,22 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
// exponent. Also could broaden sign check to cover == 0 case.
Value *Src = II->getArgOperand(0);
Value *Exp = II->getArgOperand(1);
+
+ uint64_t ConstExp;
+ if (match(Exp, m_ConstantInt(ConstExp))) {
+ // ldexp(x, K) -> fmul x, 2^K
+ const fltSemantics &FPTy =
+ Src->getType()->getScalarType()->getFltSemantics();
+
+ APFloat Scaled = scalbn(APFloat::getOne(FPTy), static_cast<int>(ConstExp),
+ APFloat::rmNearestTiesToEven);
+ if (!Scaled.isZero() && !Scaled.isInfinity()) {
+ // Skip overflow and underflow cases.
+ Constant *FPConst = ConstantFP::get(Src->getType(), Scaled);
+ return BinaryOperator::CreateFMulFMF(Src, FPConst, II);
+ }
+ }
+
Value *InnerSrc;
Value *InnerExp;
if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ldexp>(
diff --git a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
index 1ba7005f99e3d..4495b0f26042b 100644
--- a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
+++ b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
@@ -49,10 +49,7 @@ define float @fmul_by_32_if_0_oeq_zero_f32(float %x) {
define float @ldexp_by_5_if_0_oeq_zero_f32(float %x) {
; CHECK-LABEL: @ldexp_by_5_if_0_oeq_zero_f32(
-; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq float [[X:%.*]], 0.000000e+00
-; CHECK-NEXT: [[SCALED_X:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 5)
-; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select i1 [[X_IS_ZERO]], float [[SCALED_X]], float [[X]]
-; CHECK-NEXT: ret float [[SCALED_IF_DENORMAL]]
+; CHECK-NEXT: ret float [[X:%.*]]
;
%x.is.zero = fcmp oeq float %x, 0.0
%scaled.x = call float @llvm.ldexp.f32.i32(float %x, i32 5)
@@ -62,10 +59,7 @@ define float @ldexp_by_5_if_0_oeq_zero_f32(float %x) {
define <2 x float> @ldexp_by_5_if_0_oeq_zero_v2f32(<2 x float> %x) {
; CHECK-LABEL: @ldexp_by_5_if_0_oeq_zero_v2f32(
-; CHECK-NEXT: [[X_IS_ZERO:%.*]] = fcmp oeq <2 x float> [[X:%.*]], zeroinitializer
-; CHECK-NEXT: [[SCALED_X:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> splat (i32 5))
-; CHECK-NEXT: [[SCALED_IF_DENORMAL:%.*]] = select <2 x i1> [[X_IS_ZERO]], <2 x float> [[SCALED_X]], <2 x float> [[X]]
-; CHECK-NEXT: ret <2 x float> [[SCALED_IF_DENORMAL]]
+; CHECK-NEXT: ret <2 x float> [[SCALED_IF_DENORMAL:%.*]]
;
%x.is.zero = fcmp oeq <2 x float> %x, zeroinitializer
%scaled.x = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 5, i32 5>)
diff --git a/llvm/test/Transforms/InstCombine/ldexp.ll b/llvm/test/Transforms/InstCombine/ldexp.ll
index 72997eef4fd6d..9586fffe9956c 100644
--- a/llvm/test/Transforms/InstCombine/ldexp.ll
+++ b/llvm/test/Transforms/InstCombine/ldexp.ll
@@ -444,7 +444,7 @@ define float @ldexp_ldexp_different_exp_type(float %x, i32 %a, i64 %b) {
define float @ldexp_ldexp_constants(float %x) {
; CHECK-LABEL: define float @ldexp_ldexp_constants
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 32)
+; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc float [[X]], 0x41F0000000000000
; CHECK-NEXT: ret float [[LDEXP1]]
;
%ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8)
@@ -455,7 +455,7 @@ define float @ldexp_ldexp_constants(float %x) {
define float @ldexp_ldexp_constants_nsz(float %x) {
; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32)
+; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc nsz float [[X]], 0x41F0000000000000
; CHECK-NEXT: ret float [[LDEXP1]]
;
%ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 8)
@@ -466,7 +466,7 @@ define float @ldexp_ldexp_constants_nsz(float %x) {
define float @ldexp_ldexp_constants_nsz0(float %x) {
; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz0
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32)
+; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc float [[X]], 0x41F0000000000000
; CHECK-NEXT: ret float [[LDEXP1]]
;
%ldexp0 = call reassoc nsz float @llvm.ldexp.f32.i32(float %x, i32 8)
@@ -477,7 +477,7 @@ define float @ldexp_ldexp_constants_nsz0(float %x) {
define float @ldexp_ldexp_constants_nsz1(float %x) {
; CHECK-LABEL: define float @ldexp_ldexp_constants_nsz1
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32)
+; CHECK-NEXT: [[LDEXP1:%.*]] = fmul reassoc nsz float [[X]], 0x41F0000000000000
; CHECK-NEXT: ret float [[LDEXP1]]
;
%ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8)
@@ -651,7 +651,7 @@ define float @ldexp_neg150(float %x) {
define float @ldexp_neg149(float %x) {
; CHECK-LABEL: define float @ldexp_neg149
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -149)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x36A0000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -149)
@@ -661,7 +661,7 @@ define float @ldexp_neg149(float %x) {
define float @ldexp_neg148(float %x) {
; CHECK-LABEL: define float @ldexp_neg148
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -148)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x36B0000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -148)
@@ -671,7 +671,7 @@ define float @ldexp_neg148(float %x) {
define float @ldexp_neg127(float %x) {
; CHECK-LABEL: define float @ldexp_neg127
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -127)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x3800000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -127)
@@ -681,7 +681,7 @@ define float @ldexp_neg127(float %x) {
define float @ldexp_neg126(float %x) {
; CHECK-LABEL: define float @ldexp_neg126
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -126)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x3810000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -126)
@@ -691,7 +691,7 @@ define float @ldexp_neg126(float %x) {
define float @ldexp_neg125(float %x) {
; CHECK-LABEL: define float @ldexp_neg125
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -125)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x3820000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -125)
@@ -701,7 +701,7 @@ define float @ldexp_neg125(float %x) {
define float @ldexp_neg16(float %x) {
; CHECK-LABEL: define float @ldexp_neg16
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -16)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x3EF0000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -16)
@@ -711,7 +711,7 @@ define float @ldexp_neg16(float %x) {
define float @ldexp_neg8(float %x) {
; CHECK-LABEL: define float @ldexp_neg8
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -8)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 3.906250e-03
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -8)
@@ -721,7 +721,7 @@ define float @ldexp_neg8(float %x) {
define float @ldexp_neg4(float %x) {
; CHECK-LABEL: define float @ldexp_neg4
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -4)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 6.250000e-02
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -4)
@@ -731,7 +731,7 @@ define float @ldexp_neg4(float %x) {
define float @ldexp_neg2(float %x) {
; CHECK-LABEL: define float @ldexp_neg2
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -2)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 2.500000e-01
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -2)
@@ -741,7 +741,7 @@ define float @ldexp_neg2(float %x) {
define float @ldexp_neg1(float %x) {
; CHECK-LABEL: define float @ldexp_neg1
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -1)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 5.000000e-01
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -1)
@@ -760,7 +760,7 @@ define float @ldexp_0(float %x) {
define float @ldexp_1(float %x) {
; CHECK-LABEL: define float @ldexp_1
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 1)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 2.000000e+00
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 1)
@@ -770,7 +770,7 @@ define float @ldexp_1(float %x) {
define float @ldexp_2(float %x) {
; CHECK-LABEL: define float @ldexp_2
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 4.000000e+00
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2)
@@ -780,7 +780,7 @@ define float @ldexp_2(float %x) {
define float @ldexp_3(float %x) {
; CHECK-LABEL: define float @ldexp_3
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 3)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 8.000000e+00
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 3)
@@ -790,7 +790,7 @@ define float @ldexp_3(float %x) {
define float @ldexp_10(float %x) {
; CHECK-LABEL: define float @ldexp_10
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 10)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 1.024000e+03
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 10)
@@ -800,7 +800,7 @@ define float @ldexp_10(float %x) {
define float @ldexp_125(float %x) {
; CHECK-LABEL: define float @ldexp_125
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 125)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x47C0000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 125)
@@ -810,7 +810,7 @@ define float @ldexp_125(float %x) {
define float @ldexp_126(float %x) {
; CHECK-LABEL: define float @ldexp_126
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 126)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x47D0000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 126)
@@ -820,7 +820,7 @@ define float @ldexp_126(float %x) {
define float @ldexp_127(float %x) {
; CHECK-LABEL: define float @ldexp_127
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 127)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x47E0000000000000
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 127)
@@ -910,7 +910,7 @@ define float @ldexp_neg260(float %x) {
define <2 x float> @ldexp_3_vector(<2 x float> %x) {
; CHECK-LABEL: define <2 x float> @ldexp_3_vector
; CHECK-SAME: (<2 x float> [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> splat (i32 3))
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul <2 x float> [[X]], splat (float 8.000000e+00)
; CHECK-NEXT: ret <2 x float> [[LDEXP]]
;
%ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> <i32 3, i32 3>)
@@ -940,7 +940,7 @@ define <2 x float> @ldexp_3_4_vector(<2 x float> %x) {
define float @ldexp_2_flags(float %x) {
; CHECK-LABEL: define float @ldexp_2_flags
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call nsz contract float @llvm.ldexp.f32.i32(float [[X]], i32 2)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul nsz contract float [[X]], 4.000000e+00
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call contract nsz float @llvm.ldexp.f32.i32(float %x, i32 2)
@@ -950,7 +950,7 @@ define float @ldexp_2_flags(float %x) {
define float @ldexp_metadata(float %x) {
; CHECK-LABEL: define float @ldexp_metadata
; CHECK-SAME: (float [[X:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2), !foo [[META2:![0-9]+]]
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 4.000000e+00
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2), !foo !2
@@ -960,7 +960,7 @@ define float @ldexp_metadata(float %x) {
define float @ldexp_8_contractable(float %x, float %y) {
; CHECK-LABEL: define float @ldexp_8_contractable
; CHECK-SAME: (float [[X:%.*]], float [[Y:%.*]]) {
-; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X]], i32 2)
+; CHECK-NEXT: [[LDEXP:%.*]] = fmul contract float [[X]], 4.000000e+00
; CHECK-NEXT: [[FADD:%.*]] = fadd contract float [[LDEXP]], [[Y]]
; CHECK-NEXT: ret float [[FADD]]
;
|
dtcxzyw
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG

This reverts commit 757c5b3.
Reapply with the transform skipped if the scaling overflows or underflows.