diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 134eeba3996aa6..c9f6839e4b94a5 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -1992,11 +1992,12 @@ static Value *getIntToFPVal(Value *I2F, IRBuilderBase &B, unsigned DstWidth) { Value *Op = cast(I2F)->getOperand(0); // Make sure that the exponent fits inside an "int" of size DstWidth, // thus avoiding any range issues that FP has not. - unsigned BitWidth = Op->getType()->getPrimitiveSizeInBits(); - if (BitWidth < DstWidth || - (BitWidth == DstWidth && isa(I2F))) - return isa(I2F) ? B.CreateSExt(Op, B.getIntNTy(DstWidth)) - : B.CreateZExt(Op, B.getIntNTy(DstWidth)); + unsigned BitWidth = Op->getType()->getScalarSizeInBits(); + if (BitWidth < DstWidth || (BitWidth == DstWidth && isa(I2F))) { + Type *IntTy = Op->getType()->getWithNewBitWidth(DstWidth); + return isa(I2F) ? B.CreateSExt(Op, IntTy) + : B.CreateZExt(Op, IntTy); + } } return nullptr; @@ -2366,10 +2367,10 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) { hasFloatVersion(M, Name)) Ret = optimizeUnaryDoubleFP(CI, B, TLI, true); + const bool UseIntrinsic = CI->doesNotAccessMemory(); // Bail out for vectors because the code below only expects scalars. - // TODO: This could be allowed if we had a ldexp intrinsic (D14327). Type *Ty = CI->getType(); - if (Ty->isVectorTy()) + if (!UseIntrinsic && Ty->isVectorTy()) return Ret; // exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= IntSize @@ -2382,7 +2383,7 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) { // TODO: Emitting the intrinsic should not depend on whether the libcall // is available. - if (CI->doesNotAccessMemory()) { + if (UseIntrinsic) { return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp, {Ty, Exp->getType()}, {One, Exp}, CI)); diff --git a/llvm/test/Transforms/InstCombine/exp2-1.ll b/llvm/test/Transforms/InstCombine/exp2-1.ll index 5bf70320d9ec44..2dff0b08ecf97b 100644 --- a/llvm/test/Transforms/InstCombine/exp2-1.ll +++ b/llvm/test/Transforms/InstCombine/exp2-1.ll @@ -308,20 +308,15 @@ define float @sitofp_scalar_intrinsic_with_FMF(i8 %x) { define <2 x float> @sitofp_vector_intrinsic_with_FMF(<2 x i8> %x) { ; LDEXP32-LABEL: @sitofp_vector_intrinsic_with_FMF( -; LDEXP32-NEXT: [[S:%.*]] = sitofp <2 x i8> [[X:%.*]] to <2 x float> -; LDEXP32-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> [[S]]) +; LDEXP32-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32> +; LDEXP32-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> , <2 x i32> [[TMP1]]) ; LDEXP32-NEXT: ret <2 x float> [[R]] ; ; LDEXP16-LABEL: @sitofp_vector_intrinsic_with_FMF( -; LDEXP16-NEXT: [[S:%.*]] = sitofp <2 x i8> [[X:%.*]] to <2 x float> -; LDEXP16-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> [[S]]) +; LDEXP16-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i16> +; 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: [[S:%.*]] = sitofp <2 x i8> [[X:%.*]] to <2 x float> -; NOLDEXPF-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> [[S]]) -; 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]]) diff --git a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll index 3069ee65e238ad..6e5be5a19d6da5 100644 --- a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll +++ b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll @@ -39,11 +39,17 @@ define float @exp2_f32_sitofp_i8_flags(i8 %x) { } define <2 x float> @exp2_v2f32_sitofp_v2i8(<2 x i8> %x) { -; CHECK-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8( -; CHECK-SAME: <2 x i8> [[X:%.*]]) { -; CHECK-NEXT: [[ITOFP:%.*]] = sitofp <2 x i8> [[X]] to <2 x float> -; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[ITOFP]]) -; CHECK-NEXT: ret <2 x float> [[EXP2]] +; 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]] ; %itofp = sitofp <2 x i8> %x to <2 x float> %exp2 = call <2 x float> @llvm.exp2.v2f32(<2 x float> %itofp) @@ -117,11 +123,17 @@ define fp128 @exp2_fp128_sitofp_i8(i8 %x) { } define @exp2_nxv4f32_sitofp_i8( %x) { -; CHECK-LABEL: define @exp2_nxv4f32_sitofp_i8( -; CHECK-SAME: [[X:%.*]]) { -; CHECK-NEXT: [[ITOFP:%.*]] = sitofp [[X]] to -; CHECK-NEXT: [[EXP2:%.*]] = call @llvm.exp2.nxv4f32( [[ITOFP]]) -; CHECK-NEXT: ret [[EXP2]] +; 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]] ; %itofp = sitofp %x to %exp2 = call @llvm.exp2.nxv4f32( %itofp) diff --git a/llvm/test/Transforms/InstCombine/pow_fp_int.ll b/llvm/test/Transforms/InstCombine/pow_fp_int.ll index 9c1fa88f3183ea..7b194b3f8925f4 100644 --- a/llvm/test/Transforms/InstCombine/pow_fp_int.ll +++ b/llvm/test/Transforms/InstCombine/pow_fp_int.ll @@ -530,8 +530,8 @@ define double @powf_exp_const2_int_no_fast(double %base) { define <2 x float> @pow_sitofp_const_base_2_no_fast_vector(<2 x i8> %x) { ; CHECK-LABEL: define <2 x float> @pow_sitofp_const_base_2_no_fast_vector( ; CHECK-SAME: <2 x i8> [[X:%.*]]) { -; CHECK-NEXT: [[S:%.*]] = sitofp <2 x i8> [[X]] to <2 x float> -; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[S]]) +; 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]] ; %s = sitofp <2 x i8> %x to <2 x float>