Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3089,6 +3089,19 @@ 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<int>(ConstExp),
APFloat::rmNearestTiesToEven));
return BinaryOperator::CreateFMulFMF(Src, FPConst, II);
}

Value *InnerSrc;
Value *InnerExp;
if (match(Src, m_OneUse(m_Intrinsic<Intrinsic::ldexp>(
Expand Down
10 changes: 2 additions & 8 deletions llvm/test/Transforms/InstCombine/fold-select-fmul-if-zero.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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>)
Expand Down
62 changes: 36 additions & 26 deletions llvm/test/Transforms/InstCombine/ldexp.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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:%.*]] = call float @llvm.ldexp.f32.i32(float [[X]], i32 -150)
; CHECK-NEXT: [[LDEXP:%.*]] = fmul float [[X]], 0.000000e+00
; CHECK-NEXT: ret float [[LDEXP]]
;
%ldexp = call float @llvm.ldexp.f32.i32(float %x, i32 -150)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -820,17 +820,27 @@ 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)
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:%.*]] = 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>)
Expand Down Expand Up @@ -860,7 +870,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)
Expand All @@ -870,7 +880,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
Expand All @@ -880,7 +890,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]]
;
Expand Down