From 8eafbbdf5f03a8e5bee944b7004597984d47eba6 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Thu, 11 Dec 2025 21:40:24 +0100 Subject: [PATCH] Revert "InstCombine: Fold ldexp with constant exponent to fmul (#171731)" This reverts commit 5eb2ec2179b2b95be16c7f855fe8460b4a98b5b1. --- .../InstCombine/InstCombineCalls.cpp | 13 ---- .../InstCombine/fold-select-fmul-if-zero.ll | 10 ++- llvm/test/Transforms/InstCombine/ldexp.ll | 62 ++++++++----------- 3 files changed, 34 insertions(+), 51 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index b498bafb3caaa..85602a5a7575a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3089,19 +3089,6 @@ 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(); - Constant *FPConst = - ConstantFP::get(Src->getType(), scalbn(APFloat::getOne(FPTy), - static_cast(ConstExp), - APFloat::rmNearestTiesToEven)); - return BinaryOperator::CreateFMulFMF(Src, FPConst, II); - } - Value *InnerSrc; Value *InnerExp; if (match(Src, m_OneUse(m_Intrinsic( 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 4495b0f26042b..1ba7005f99e3d 100644 --- a/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll +++ b/llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll @@ -49,7 +49,10 @@ 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: ret float [[X:%.*]] +; 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]] ; %x.is.zero = fcmp oeq float %x, 0.0 %scaled.x = call float @llvm.ldexp.f32.i32(float %x, i32 5) @@ -59,7 +62,10 @@ 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: ret <2 x float> [[SCALED_IF_DENORMAL:%.*]] +; 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]] ; %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> ) diff --git a/llvm/test/Transforms/InstCombine/ldexp.ll b/llvm/test/Transforms/InstCombine/ldexp.ll index 43e80b1a1e588..8908d476b4a2c 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:%.*]] = fmul reassoc float [[X]], 0x41F0000000000000 +; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc float @llvm.ldexp.f32.i32(float [[X]], i32 32) ; 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:%.*]] = fmul reassoc nsz float [[X]], 0x41F0000000000000 +; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32) ; 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:%.*]] = fmul reassoc float [[X]], 0x41F0000000000000 +; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32) ; 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:%.*]] = fmul reassoc nsz float [[X]], 0x41F0000000000000 +; CHECK-NEXT: [[LDEXP1:%.*]] = call reassoc nsz float @llvm.ldexp.f32.i32(float [[X]], i32 32) ; CHECK-NEXT: ret float [[LDEXP1]] ; %ldexp0 = call reassoc float @llvm.ldexp.f32.i32(float %x, i32 8) @@ -641,7 +641,7 @@ define float @ldexp_ldexp_0(float %x, i32 %y) { define float @ldexp_neg150(float %x) { ; CHECK-LABEL: define float @ldexp_neg150 ; CHECK-SAME: (float [[X:%.*]]) { -; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -150) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -150) @@ -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:%.*]] = fmul float [[X]], 0x36A0000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -149) ; 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:%.*]] = fmul float [[X]], 0x36B0000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -148) ; 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:%.*]] = fmul float [[X]], 0x3800000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -127) ; 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:%.*]] = fmul float [[X]], 0x3810000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -126) ; 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:%.*]] = fmul float [[X]], 0x3820000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -125) ; 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:%.*]] = fmul float [[X]], 0x3EF0000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -16) ; 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:%.*]] = fmul float [[X]], 3.906250e-03 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -8) ; 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:%.*]] = fmul float [[X]], 6.250000e-02 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -4) ; 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:%.*]] = fmul float [[X]], 2.500000e-01 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -2) ; 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:%.*]] = fmul float [[X]], 5.000000e-01 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -1) ; 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:%.*]] = fmul float [[X]], 2.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 1) ; 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:%.*]] = fmul float [[X]], 4.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2) ; 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:%.*]] = fmul float [[X]], 8.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 3) ; 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:%.*]] = fmul float [[X]], 1.024000e+03 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 10) ; 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:%.*]] = fmul float [[X]], 0x47C0000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 125) ; 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:%.*]] = fmul float [[X]], 0x47D0000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 126) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 126) @@ -820,27 +820,17 @@ 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:%.*]] = fmul float [[X]], 0x47E0000000000000 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 127) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 127) ret float %ldexp } -define float @ldexp_128(float %x) { -; CHECK-LABEL: define float @ldexp_128 -; CHECK-SAME: (float [[X:%.*]]) { -; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0x7FF0000000000000 -; CHECK-NEXT: ret float [[LDEXP]] -; - %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 128) - ret float %ldexp -} - 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:%.*]] = fmul <2 x float> [[X]], splat (float 8.000000e+00) +; CHECK-NEXT: [[LDEXP:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> [[X]], <2 x i32> splat (i32 3)) ; CHECK-NEXT: ret <2 x float> [[LDEXP]] ; %ldexp = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> %x, <2 x i32> ) @@ -870,7 +860,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:%.*]] = fmul nsz contract float [[X]], 4.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call nsz contract float @llvm.ldexp.f32.i32(float [[X]], i32 2) ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call contract nsz float @llvm.ldexp.f32.i32(float %x, i32 2) @@ -880,7 +870,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:%.*]] = fmul float [[X]], 4.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 2), !foo [[META2:![0-9]+]] ; CHECK-NEXT: ret float [[LDEXP]] ; %ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 2), !foo !2 @@ -890,7 +880,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:%.*]] = fmul contract float [[X]], 4.000000e+00 +; CHECK-NEXT: [[LDEXP:%.*]] = call contract float @llvm.ldexp.f32.i32(float [[X]], i32 2) ; CHECK-NEXT: [[FADD:%.*]] = fadd contract float [[LDEXP]], [[Y]] ; CHECK-NEXT: ret float [[FADD]] ;