diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index eb1224abf00e2..a91c3ff930616 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2376,7 +2376,13 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) { hasFloatVersion(M, Name)) Ret = optimizeUnaryDoubleFP(CI, B, TLI, true); - const bool UseIntrinsic = CI->doesNotAccessMemory(); + // If we have an llvm.exp2 intrinsic, emit the llvm.ldexp intrinsic. If we + // have the libcall, emit the libcall. + // + // TODO: In principle we should be able to just always use the intrinsic for + // any doesNotAccessMemory callsite. + + const bool UseIntrinsic = Callee->isIntrinsic(); // Bail out for vectors because the code below only expects scalars. Type *Ty = CI->getType(); if (!UseIntrinsic && Ty->isVectorTy()) @@ -2386,12 +2392,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) { // exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < IntSize Value *Op = CI->getArgOperand(0); if ((isa(Op) || isa(Op)) && - hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) { + (UseIntrinsic || + hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) { if (Value *Exp = getIntToFPVal(Op, B, TLI->getIntSize())) { Constant *One = ConstantFP::get(Ty, 1.0); - // TODO: Emitting the intrinsic should not depend on whether the libcall - // is available. if (UseIntrinsic) { return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp, {Ty, Exp->getType()}, diff --git a/llvm/test/LTO/X86/triple-init2.ll b/llvm/test/LTO/X86/triple-init2.ll index 2638180ef33c6..bc5ecf9785a28 100644 --- a/llvm/test/LTO/X86/triple-init2.ll +++ b/llvm/test/LTO/X86/triple-init2.ll @@ -11,21 +11,20 @@ ; RUN: llvm-lto2 run -r %t1,main,plx -o %t2 %t1 ; RUN: llvm-nm %t2.1 | FileCheck %s -; We check that LTO will be aware of target triple and prevent exp2 to ldexpf +; We check that LTO will be aware of target triple and prevent pow to exp10 ; transformation on Windows. -; CHECK: U exp2f +; CHECK: U powf target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-windows-msvc19.11.0" +declare float @llvm.pow.f32(float, float) + define dso_local i32 @main(i32 %argc, ptr nocapture readnone %argv) local_unnamed_addr { entry: %conv = sitofp i32 %argc to float - %exp2 = tail call float @llvm.exp2.f32(float %conv) + %exp2 = tail call float @llvm.pow.f32(float 10.0, float %conv) %conv1 = fptosi float %exp2 to i32 ret i32 %conv1 } -; Function Attrs: nounwind readnone speculatable -declare float @llvm.exp2.f32(float) - diff --git a/llvm/test/Transforms/InstCombine/exp2-1.ll b/llvm/test/Transforms/InstCombine/exp2-1.ll index 2dff0b08ecf97..d8bd0a4d8159d 100644 --- a/llvm/test/Transforms/InstCombine/exp2-1.ll +++ b/llvm/test/Transforms/InstCombine/exp2-1.ll @@ -242,8 +242,8 @@ define double @test_simplify9(i8 zeroext %x) { ; NOLDEXPF-NEXT: ret double [[RET]] ; ; NOLDEXP-LABEL: @test_simplify9( -; NOLDEXP-NEXT: [[CONV:%.*]] = uitofp i8 [[X:%.*]] to double -; NOLDEXP-NEXT: [[RET:%.*]] = call double @llvm.exp2.f64(double [[CONV]]) +; NOLDEXP-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32 +; NOLDEXP-NEXT: [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]]) ; NOLDEXP-NEXT: ret double [[RET]] ; %conv = uitofp i8 %x to double @@ -263,13 +263,13 @@ define float @test_simplify10(i8 zeroext %x) { ; LDEXP16-NEXT: ret float [[RET]] ; ; NOLDEXPF-LABEL: @test_simplify10( -; NOLDEXPF-NEXT: [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float -; NOLDEXPF-NEXT: [[RET:%.*]] = call float @llvm.exp2.f32(float [[CONV]]) +; NOLDEXPF-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32 +; NOLDEXPF-NEXT: [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) ; NOLDEXPF-NEXT: ret float [[RET]] ; ; NOLDEXP-LABEL: @test_simplify10( -; NOLDEXP-NEXT: [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float -; NOLDEXP-NEXT: [[RET:%.*]] = call float @llvm.exp2.f32(float [[CONV]]) +; NOLDEXP-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32 +; NOLDEXP-NEXT: [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) ; NOLDEXP-NEXT: ret float [[RET]] ; %conv = uitofp i8 %x to float @@ -289,13 +289,13 @@ define float @sitofp_scalar_intrinsic_with_FMF(i8 %x) { ; LDEXP16-NEXT: ret float [[R]] ; ; NOLDEXPF-LABEL: @sitofp_scalar_intrinsic_with_FMF( -; NOLDEXPF-NEXT: [[S:%.*]] = sitofp i8 [[X:%.*]] to float -; NOLDEXPF-NEXT: [[R:%.*]] = tail call nnan float @llvm.exp2.f32(float [[S]]) +; NOLDEXPF-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32 +; NOLDEXPF-NEXT: [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) ; NOLDEXPF-NEXT: ret float [[R]] ; ; NOLDEXP-LABEL: @sitofp_scalar_intrinsic_with_FMF( -; NOLDEXP-NEXT: [[S:%.*]] = sitofp i8 [[X:%.*]] to float -; NOLDEXP-NEXT: [[R:%.*]] = tail call nnan float @llvm.exp2.f32(float [[S]]) +; NOLDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32 +; NOLDEXP-NEXT: [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) ; NOLDEXP-NEXT: ret float [[R]] ; %s = sitofp i8 %x to float @@ -317,9 +317,14 @@ define <2 x float> @sitofp_vector_intrinsic_with_FMF(<2 x i8> %x) { ; LDEXP16-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i16(<2 x float> , <2 x i16> [[TMP1]]) ; LDEXP16-NEXT: ret <2 x float> [[R]] ; +; NOLDEXPF-LABEL: @sitofp_vector_intrinsic_with_FMF( +; NOLDEXPF-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32> +; NOLDEXPF-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[TMP1]]) +; NOLDEXPF-NEXT: ret <2 x float> [[R]] +; ; NOLDEXP-LABEL: @sitofp_vector_intrinsic_with_FMF( -; NOLDEXP-NEXT: [[S:%.*]] = sitofp <2 x i8> [[X:%.*]] to <2 x float> -; NOLDEXP-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> [[S]]) +; NOLDEXP-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32> +; NOLDEXP-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[TMP1]]) ; NOLDEXP-NEXT: ret <2 x float> [[R]] ; %s = sitofp <2 x i8> %x to <2 x float> diff --git a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll index 6e5be5a19d6da..969020140cb33 100644 --- a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll +++ b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll @@ -1,19 +1,13 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 -; RUN: opt -S -passes=instcombine %s | FileCheck -check-prefixes=CHECK,LDEXP %s -; RUN: opt -S -passes=instcombine -disable-builtin=ldexpf -disable-builtin=ldexp -disable-builtin=ldexpl %s | FileCheck -check-prefixes=CHECK,NOLDEXP %s +; RUN: opt -S -passes=instcombine %s | FileCheck %s +; RUN: opt -S -passes=instcombine -disable-builtin=ldexpf -disable-builtin=ldexp -disable-builtin=ldexpl %s | FileCheck %s define float @exp2_f32_sitofp_i8(i8 %x) { -; LDEXP-LABEL: define float @exp2_f32_sitofp_i8( -; LDEXP-SAME: i8 [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 -; LDEXP-NEXT: [[LDEXPF:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) -; LDEXP-NEXT: ret float [[LDEXPF]] -; -; NOLDEXP-LABEL: define float @exp2_f32_sitofp_i8( -; NOLDEXP-SAME: i8 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to float -; NOLDEXP-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[ITOFP]]) -; NOLDEXP-NEXT: ret float [[EXP2]] +; CHECK-LABEL: define float @exp2_f32_sitofp_i8( +; CHECK-SAME: i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 +; CHECK-NEXT: [[EXP2:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) +; CHECK-NEXT: ret float [[EXP2]] ; %itofp = sitofp i8 %x to float %exp2 = call float @llvm.exp2.f32(float %itofp) @@ -21,17 +15,11 @@ define float @exp2_f32_sitofp_i8(i8 %x) { } define float @exp2_f32_sitofp_i8_flags(i8 %x) { -; LDEXP-LABEL: define float @exp2_f32_sitofp_i8_flags( -; LDEXP-SAME: i8 [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 -; LDEXP-NEXT: [[LDEXPF:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) -; LDEXP-NEXT: ret float [[LDEXPF]] -; -; NOLDEXP-LABEL: define float @exp2_f32_sitofp_i8_flags( -; NOLDEXP-SAME: i8 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to float -; NOLDEXP-NEXT: [[EXP2:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[ITOFP]]) -; NOLDEXP-NEXT: ret float [[EXP2]] +; CHECK-LABEL: define float @exp2_f32_sitofp_i8_flags( +; CHECK-SAME: i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 +; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) +; CHECK-NEXT: ret float [[EXP2]] ; %itofp = sitofp i8 %x to float %exp2 = call nnan ninf float @llvm.exp2.f32(float %itofp) @@ -39,17 +27,11 @@ define float @exp2_f32_sitofp_i8_flags(i8 %x) { } define <2 x float> @exp2_v2f32_sitofp_v2i8(<2 x i8> %x) { -; LDEXP-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8( -; LDEXP-SAME: <2 x i8> [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32> -; LDEXP-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[TMP1]]) -; LDEXP-NEXT: ret <2 x float> [[EXP2]] -; -; NOLDEXP-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8( -; NOLDEXP-SAME: <2 x i8> [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <2 x i8> [[X]] to <2 x float> -; NOLDEXP-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[ITOFP]]) -; NOLDEXP-NEXT: ret <2 x float> [[EXP2]] +; CHECK-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8( +; CHECK-SAME: <2 x i8> [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32> +; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[TMP1]]) +; CHECK-NEXT: ret <2 x float> [[EXP2]] ; %itofp = sitofp <2 x i8> %x to <2 x float> %exp2 = call <2 x float> @llvm.exp2.v2f32(<2 x float> %itofp) @@ -57,17 +39,11 @@ define <2 x float> @exp2_v2f32_sitofp_v2i8(<2 x i8> %x) { } define float @exp2_f32_uitofp_i8(i8 %x) { -; LDEXP-LABEL: define float @exp2_f32_uitofp_i8( -; LDEXP-SAME: i8 [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i32 -; LDEXP-NEXT: [[LDEXPF:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) -; LDEXP-NEXT: ret float [[LDEXPF]] -; -; NOLDEXP-LABEL: define float @exp2_f32_uitofp_i8( -; NOLDEXP-SAME: i8 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = uitofp i8 [[X]] to float -; NOLDEXP-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[ITOFP]]) -; NOLDEXP-NEXT: ret float [[EXP2]] +; CHECK-LABEL: define float @exp2_f32_uitofp_i8( +; CHECK-SAME: i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i32 +; CHECK-NEXT: [[EXP2:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]]) +; CHECK-NEXT: ret float [[EXP2]] ; %itofp = uitofp i8 %x to float %exp2 = call float @llvm.exp2.f32(float %itofp) @@ -77,8 +53,8 @@ define float @exp2_f32_uitofp_i8(i8 %x) { define half @exp2_f16_sitofp_i8(i8 %x) { ; CHECK-LABEL: define half @exp2_f16_sitofp_i8( ; CHECK-SAME: i8 [[X:%.*]]) { -; CHECK-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to half -; CHECK-NEXT: [[EXP2:%.*]] = call half @llvm.exp2.f16(half [[ITOFP]]) +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 +; CHECK-NEXT: [[EXP2:%.*]] = call half @llvm.ldexp.f16.i32(half 0xH3C00, i32 [[TMP1]]) ; CHECK-NEXT: ret half [[EXP2]] ; %itofp = sitofp i8 %x to half @@ -87,17 +63,11 @@ define half @exp2_f16_sitofp_i8(i8 %x) { } define double @exp2_f64_sitofp_i8(i8 %x) { -; LDEXP-LABEL: define double @exp2_f64_sitofp_i8( -; LDEXP-SAME: i8 [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 -; LDEXP-NEXT: [[LDEXP:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]]) -; LDEXP-NEXT: ret double [[LDEXP]] -; -; NOLDEXP-LABEL: define double @exp2_f64_sitofp_i8( -; NOLDEXP-SAME: i8 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to double -; NOLDEXP-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[ITOFP]]) -; NOLDEXP-NEXT: ret double [[EXP2]] +; CHECK-LABEL: define double @exp2_f64_sitofp_i8( +; CHECK-SAME: i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 +; CHECK-NEXT: [[EXP2:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]]) +; CHECK-NEXT: ret double [[EXP2]] ; %itofp = sitofp i8 %x to double %exp2 = call double @llvm.exp2.f64(double %itofp) @@ -105,17 +75,11 @@ define double @exp2_f64_sitofp_i8(i8 %x) { } define fp128 @exp2_fp128_sitofp_i8(i8 %x) { -; LDEXP-LABEL: define fp128 @exp2_fp128_sitofp_i8( -; LDEXP-SAME: i8 [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 -; LDEXP-NEXT: [[LDEXPL:%.*]] = call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]]) -; LDEXP-NEXT: ret fp128 [[LDEXPL]] -; -; NOLDEXP-LABEL: define fp128 @exp2_fp128_sitofp_i8( -; NOLDEXP-SAME: i8 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to fp128 -; NOLDEXP-NEXT: [[EXP2:%.*]] = call fp128 @llvm.exp2.f128(fp128 [[ITOFP]]) -; NOLDEXP-NEXT: ret fp128 [[EXP2]] +; CHECK-LABEL: define fp128 @exp2_fp128_sitofp_i8( +; CHECK-SAME: i8 [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32 +; CHECK-NEXT: [[EXP2:%.*]] = call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]]) +; CHECK-NEXT: ret fp128 [[EXP2]] ; %itofp = sitofp i8 %x to fp128 %exp2 = call fp128 @llvm.exp2.fp128(fp128 %itofp) @@ -123,17 +87,11 @@ define fp128 @exp2_fp128_sitofp_i8(i8 %x) { } define @exp2_nxv4f32_sitofp_i8( %x) { -; LDEXP-LABEL: define @exp2_nxv4f32_sitofp_i8( -; LDEXP-SAME: [[X:%.*]]) { -; LDEXP-NEXT: [[TMP1:%.*]] = sext [[X]] to -; LDEXP-NEXT: [[EXP2:%.*]] = call @llvm.ldexp.nxv4f32.nxv4i32( shufflevector ( insertelement ( poison, float 1.000000e+00, i64 0), poison, zeroinitializer), [[TMP1]]) -; LDEXP-NEXT: ret [[EXP2]] -; -; NOLDEXP-LABEL: define @exp2_nxv4f32_sitofp_i8( -; NOLDEXP-SAME: [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp [[X]] to -; NOLDEXP-NEXT: [[EXP2:%.*]] = call @llvm.exp2.nxv4f32( [[ITOFP]]) -; NOLDEXP-NEXT: ret [[EXP2]] +; CHECK-LABEL: define @exp2_nxv4f32_sitofp_i8( +; CHECK-SAME: [[X:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = sext [[X]] to +; CHECK-NEXT: [[EXP2:%.*]] = call @llvm.ldexp.nxv4f32.nxv4i32( shufflevector ( insertelement ( poison, float 1.000000e+00, i64 0), poison, zeroinitializer), [[TMP1]]) +; CHECK-NEXT: ret [[EXP2]] ; %itofp = sitofp %x to %exp2 = call @llvm.exp2.nxv4f32( %itofp) diff --git a/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll b/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll index b61f8809bd259..cb51e92093263 100644 --- a/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll +++ b/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll @@ -5,16 +5,10 @@ define float @pow_sitofp_f32_const_base_2(i32 %x) { -; LDEXP-LABEL: define float @pow_sitofp_f32_const_base_2( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXPF:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]]) -; LDEXP-NEXT: ret float [[LDEXPF]] -; -; NOLDEXP-LABEL: define float @pow_sitofp_f32_const_base_2( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to float -; NOLDEXP-NEXT: [[POW:%.*]] = tail call float @llvm.exp2.f32(float [[ITOFP]]) -; NOLDEXP-NEXT: ret float [[POW]] +; CHECK-LABEL: define float @pow_sitofp_f32_const_base_2( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]]) +; CHECK-NEXT: ret float [[EXP2]] ; %itofp = sitofp i32 %x to float %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %itofp) @@ -22,16 +16,10 @@ define float @pow_sitofp_f32_const_base_2(i32 %x) { } define float @pow_sitofp_f32_const_base_2__flags(i32 %x) { -; LDEXP-LABEL: define float @pow_sitofp_f32_const_base_2__flags( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXPF:%.*]] = tail call nnan nsz float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]]) -; LDEXP-NEXT: ret float [[LDEXPF]] -; -; NOLDEXP-LABEL: define float @pow_sitofp_f32_const_base_2__flags( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to float -; NOLDEXP-NEXT: [[EXP2:%.*]] = tail call nnan nsz float @llvm.exp2.f32(float [[ITOFP]]) -; NOLDEXP-NEXT: ret float [[EXP2]] +; CHECK-LABEL: define float @pow_sitofp_f32_const_base_2__flags( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call nnan nsz float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]]) +; CHECK-NEXT: ret float [[EXP2]] ; %itofp = sitofp i32 %x to float %pow = tail call nsz nnan float @llvm.pow.f32(float 2.000000e+00, float %itofp) @@ -115,16 +103,10 @@ define float @pow_sitofp_f32_const_base_16(i32 %x) { } define double @pow_sitofp_f64_const_base_2(i32 %x) { -; LDEXP-LABEL: define double @pow_sitofp_f64_const_base_2( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXP:%.*]] = tail call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[X]]) -; LDEXP-NEXT: ret double [[LDEXP]] -; -; NOLDEXP-LABEL: define double @pow_sitofp_f64_const_base_2( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to double -; NOLDEXP-NEXT: [[POW:%.*]] = tail call double @llvm.exp2.f64(double [[ITOFP]]) -; NOLDEXP-NEXT: ret double [[POW]] +; CHECK-LABEL: define double @pow_sitofp_f64_const_base_2( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[X]]) +; CHECK-NEXT: ret double [[EXP2]] ; %itofp = sitofp i32 %x to double %pow = tail call double @llvm.pow.f64(double 2.000000e+00, double %itofp) @@ -144,16 +126,10 @@ define half @pow_sitofp_f16_const_base_2(i32 %x) { } define <2 x float> @pow_sitofp_v2f32_const_base_2(<2 x i32> %x) { -; LDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2( -; LDEXP-SAME: <2 x i32> [[X:%.*]]) { -; LDEXP-NEXT: [[EXP2:%.*]] = tail call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[X]]) -; LDEXP-NEXT: ret <2 x float> [[EXP2]] -; -; NOLDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2( -; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float> -; NOLDEXP-NEXT: [[POW:%.*]] = tail call <2 x float> @llvm.exp2.v2f32(<2 x float> [[ITOFP]]) -; NOLDEXP-NEXT: ret <2 x float> [[POW]] +; CHECK-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2( +; CHECK-SAME: <2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[X]]) +; CHECK-NEXT: ret <2 x float> [[EXP2]] ; %itofp = sitofp <2 x i32> %x to <2 x float> %pow = tail call <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %itofp) @@ -199,16 +175,10 @@ define <2 x float> @pow_sitofp_v2f32_const_base_mixed_2(<2 x i32> %x) { } define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(<2 x i32> %x) { -; LDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags( -; LDEXP-SAME: <2 x i32> [[X:%.*]]) { -; LDEXP-NEXT: [[EXP2:%.*]] = tail call nsz afn <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[X]]) -; LDEXP-NEXT: ret <2 x float> [[EXP2]] -; -; NOLDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags( -; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float> -; NOLDEXP-NEXT: [[POW:%.*]] = tail call nsz afn <2 x float> @llvm.exp2.v2f32(<2 x float> [[ITOFP]]) -; NOLDEXP-NEXT: ret <2 x float> [[POW]] +; CHECK-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags( +; CHECK-SAME: <2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call nsz afn <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[X]]) +; CHECK-NEXT: ret <2 x float> [[EXP2]] ; %itofp = sitofp <2 x i32> %x to <2 x float> %pow = tail call nsz afn <2 x float> @llvm.pow.v2f32(<2 x float> , <2 x float> %itofp) @@ -216,16 +186,10 @@ define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(<2 x i32> %x) { } define @pow_sitofp_nxv4f32_const_base_2( %x) { -; LDEXP-LABEL: define @pow_sitofp_nxv4f32_const_base_2( -; LDEXP-SAME: [[X:%.*]]) { -; LDEXP-NEXT: [[EXP2:%.*]] = tail call @llvm.ldexp.nxv4f32.nxv4i32( shufflevector ( insertelement ( poison, float 1.000000e+00, i64 0), poison, zeroinitializer), [[X]]) -; LDEXP-NEXT: ret [[EXP2]] -; -; NOLDEXP-LABEL: define @pow_sitofp_nxv4f32_const_base_2( -; NOLDEXP-SAME: [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp [[X]] to -; NOLDEXP-NEXT: [[POW:%.*]] = tail call @llvm.exp2.nxv4f32( [[ITOFP]]) -; NOLDEXP-NEXT: ret [[POW]] +; CHECK-LABEL: define @pow_sitofp_nxv4f32_const_base_2( +; CHECK-SAME: [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call @llvm.ldexp.nxv4f32.nxv4i32( shufflevector ( insertelement ( poison, float 1.000000e+00, i64 0), poison, zeroinitializer), [[X]]) +; CHECK-NEXT: ret [[EXP2]] ; %itofp = sitofp %x to %pow = tail call @llvm.pow.nxv4f32( splat (float 2.0), %itofp) @@ -233,16 +197,10 @@ define @pow_sitofp_nxv4f32_const_base_2( } define <2 x half> @pow_sitofp_v2f16_const_base_2(<2 x i32> %x) { -; LDEXP-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2( -; LDEXP-SAME: <2 x i32> [[X:%.*]]) { -; LDEXP-NEXT: [[EXP2:%.*]] = tail call <2 x half> @llvm.ldexp.v2f16.v2i32(<2 x half> , <2 x i32> [[X]]) -; LDEXP-NEXT: ret <2 x half> [[EXP2]] -; -; NOLDEXP-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2( -; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half> -; NOLDEXP-NEXT: [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[ITOFP]]) -; NOLDEXP-NEXT: ret <2 x half> [[EXP2]] +; CHECK-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2( +; CHECK-SAME: <2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call <2 x half> @llvm.ldexp.v2f16.v2i32(<2 x half> , <2 x i32> [[X]]) +; CHECK-NEXT: ret <2 x half> [[EXP2]] ; %itofp = sitofp <2 x i32> %x to <2 x half> %pow = tail call <2 x half> @llvm.pow.v2f16(<2 x half> , <2 x half> %itofp) @@ -250,16 +208,10 @@ define <2 x half> @pow_sitofp_v2f16_const_base_2(<2 x i32> %x) { } define <2 x double> @pow_sitofp_v2f64_const_base_2(<2 x i32> %x) { -; LDEXP-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2( -; LDEXP-SAME: <2 x i32> [[X:%.*]]) { -; LDEXP-NEXT: [[EXP2:%.*]] = tail call <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double> , <2 x i32> [[X]]) -; LDEXP-NEXT: ret <2 x double> [[EXP2]] -; -; NOLDEXP-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2( -; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double> -; NOLDEXP-NEXT: [[EXP2:%.*]] = tail call <2 x double> @llvm.exp2.v2f64(<2 x double> [[ITOFP]]) -; NOLDEXP-NEXT: ret <2 x double> [[EXP2]] +; CHECK-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2( +; CHECK-SAME: <2 x i32> [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double> , <2 x i32> [[X]]) +; CHECK-NEXT: ret <2 x double> [[EXP2]] ; %itofp = sitofp <2 x i32> %x to <2 x double> %pow = tail call <2 x double> @llvm.pow.v2f64(<2 x double> , <2 x double> %itofp) @@ -333,16 +285,10 @@ define <2 x double> @pow_sitofp_v2f64_const_base_8(<2 x i32> %x) { } define fp128 @pow_sitofp_fp128_const_base_2(i32 %x) { -; LDEXP-LABEL: define fp128 @pow_sitofp_fp128_const_base_2( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXPL:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[X]]) -; LDEXP-NEXT: ret fp128 [[LDEXPL]] -; -; NOLDEXP-LABEL: define fp128 @pow_sitofp_fp128_const_base_2( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to fp128 -; NOLDEXP-NEXT: [[POW:%.*]] = tail call fp128 @llvm.exp2.f128(fp128 [[ITOFP]]) -; NOLDEXP-NEXT: ret fp128 [[POW]] +; CHECK-LABEL: define fp128 @pow_sitofp_fp128_const_base_2( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[X]]) +; CHECK-NEXT: ret fp128 [[EXP2]] ; %itofp = sitofp i32 %x to fp128 %pow = tail call fp128 @llvm.pow.fp128(fp128 0xL00000000000000004000000000000000, fp128 %itofp) @@ -412,16 +358,10 @@ define float @libcall_powf_sitofp_f32_const_base_2__flags(i32 %x) { } define float @readnone_libcall_powf_sitofp_f32_const_base_2(i32 %x) { -; LDEXP-LABEL: define float @readnone_libcall_powf_sitofp_f32_const_base_2( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXPF:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]]) -; LDEXP-NEXT: ret float [[LDEXPF]] -; -; NOLDEXP-LABEL: define float @readnone_libcall_powf_sitofp_f32_const_base_2( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to float -; NOLDEXP-NEXT: [[POW:%.*]] = tail call float @llvm.exp2.f32(float [[ITOFP]]) -; NOLDEXP-NEXT: ret float [[POW]] +; CHECK-LABEL: define float @readnone_libcall_powf_sitofp_f32_const_base_2( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[X]]) +; CHECK-NEXT: ret float [[EXP2]] ; %itofp = sitofp i32 %x to float %pow = tail call float @powf(float 2.000000e+00, float %itofp) memory(none) @@ -429,16 +369,10 @@ define float @readnone_libcall_powf_sitofp_f32_const_base_2(i32 %x) { } define double @readnone_libcall_pow_sitofp_f32_const_base_2(i32 %x) { -; LDEXP-LABEL: define double @readnone_libcall_pow_sitofp_f32_const_base_2( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXP:%.*]] = tail call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[X]]) -; LDEXP-NEXT: ret double [[LDEXP]] -; -; NOLDEXP-LABEL: define double @readnone_libcall_pow_sitofp_f32_const_base_2( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to double -; NOLDEXP-NEXT: [[POW:%.*]] = tail call double @llvm.exp2.f64(double [[ITOFP]]) -; NOLDEXP-NEXT: ret double [[POW]] +; CHECK-LABEL: define double @readnone_libcall_pow_sitofp_f32_const_base_2( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[X]]) +; CHECK-NEXT: ret double [[EXP2]] ; %itofp = sitofp i32 %x to double %pow = tail call double @pow(double 2.000000e+00, double %itofp) memory(none) @@ -446,16 +380,10 @@ define double @readnone_libcall_pow_sitofp_f32_const_base_2(i32 %x) { } define fp128 @readnone_libcall_powl_sitofp_fp128_const_base_2(i32 %x) { -; LDEXP-LABEL: define fp128 @readnone_libcall_powl_sitofp_fp128_const_base_2( -; LDEXP-SAME: i32 [[X:%.*]]) { -; LDEXP-NEXT: [[LDEXPL:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[X]]) -; LDEXP-NEXT: ret fp128 [[LDEXPL]] -; -; NOLDEXP-LABEL: define fp128 @readnone_libcall_powl_sitofp_fp128_const_base_2( -; NOLDEXP-SAME: i32 [[X:%.*]]) { -; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i32 [[X]] to fp128 -; NOLDEXP-NEXT: [[POW:%.*]] = tail call fp128 @llvm.exp2.f128(fp128 [[ITOFP]]) -; NOLDEXP-NEXT: ret fp128 [[POW]] +; CHECK-LABEL: define fp128 @readnone_libcall_powl_sitofp_fp128_const_base_2( +; CHECK-SAME: i32 [[X:%.*]]) { +; CHECK-NEXT: [[EXP2:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[X]]) +; CHECK-NEXT: ret fp128 [[EXP2]] ; %itofp = sitofp i32 %x to fp128 %pow = tail call fp128 @powl(fp128 0xL00000000000000004000000000000000, fp128 %itofp) memory(none)