[llvm] SimplifyLibCalls: Prefer to emit intrinsic in pow(2, x) -> ldexp(1, x) (PR #92363)

via llvm-commits llvm-commits at lists.llvm.org
Thu May 16 01:32:24 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Matt Arsenault (arsenm)

<details>
<summary>Changes</summary>



---

Patch is 30.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/92363.diff


4 Files Affected:

- (modified) llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp (+13-5) 
- (added) llvm/test/Transforms/InstCombine/pow-to-ldexp.ll (+492) 
- (modified) llvm/test/Transforms/InstCombine/pow_fp_int.ll (+3-3) 
- (modified) llvm/test/Transforms/InstCombine/pow_fp_int16.ll (+3-3) 


``````````diff
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index c9f6839e4b94a..c9567b740026b 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2092,11 +2092,19 @@ Value *LibCallSimplifier::replacePowWithExp(CallInst *Pow, IRBuilderBase &B) {
   if (!Ty->isVectorTy() && match(Base, m_SpecificFP(2.0)) &&
       (isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
       hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
-    if (Value *ExpoI = getIntToFPVal(Expo, B, TLI->getIntSize()))
-      return copyFlags(*Pow,
-                       emitBinaryFloatFnCall(ConstantFP::get(Ty, 1.0), ExpoI,
-                                             TLI, LibFunc_ldexp, LibFunc_ldexpf,
-                                             LibFunc_ldexpl, B, NoAttrs));
+    if (Value *ExpoI = getIntToFPVal(Expo, B, TLI->getIntSize())) {
+      Constant *One = ConstantFP::get(Ty, 1.0);
+
+      if (Pow->doesNotAccessMemory()) {
+        return copyFlags(*Pow, B.CreateIntrinsic(Intrinsic::ldexp,
+                                                 {Ty, ExpoI->getType()},
+                                                 {One, ExpoI}, Pow, "exp2"));
+      }
+
+      return copyFlags(*Pow, emitBinaryFloatFnCall(
+                                 One, ExpoI, TLI, LibFunc_ldexp, LibFunc_ldexpf,
+                                 LibFunc_ldexpl, B, NoAttrs));
+    }
   }
 
   // pow(2.0 ** n, x) -> exp2(n * x)
diff --git a/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll b/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll
new file mode 100644
index 0000000000000..27249dd5d72ae
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/pow-to-ldexp.ll
@@ -0,0 +1,492 @@
+; 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,LDEXP-EXP2 %s
+; RUN: opt -S -passes=instcombine -disable-builtin=exp2f -disable-builtin=exp2 -disable-builtin=exp2l %s | FileCheck -check-prefixes=CHECK,LDEXP,LDEXP-NOEXP2 %s
+; RUN: opt -S -passes=instcombine -disable-builtin=ldexpf -disable-builtin=ldexp -disable-builtin=ldexpl %s | FileCheck -check-prefixes=CHECK,NOLDEXP %s
+
+
+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]]
+;
+  %itofp = sitofp i32 %x to float
+  %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %itofp)
+  ret float %pow
+}
+
+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]]
+;
+  %itofp = sitofp i32 %x to float
+  %pow = tail call nsz nnan float @llvm.pow.f32(float 2.000000e+00, float %itofp)
+  ret float %pow
+}
+
+define float @pow_uitofp_f32_const_base_2(i32 %x) {
+; LDEXP-EXP2-LABEL: define float @pow_uitofp_f32_const_base_2(
+; LDEXP-EXP2-SAME: i32 [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[ITOFP]])
+; LDEXP-EXP2-NEXT:    ret float [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define float @pow_uitofp_f32_const_base_2(
+; LDEXP-NOEXP2-SAME: i32 [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 2.000000e+00, float [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret float [[POW]]
+;
+; NOLDEXP-LABEL: define float @pow_uitofp_f32_const_base_2(
+; NOLDEXP-SAME: i32 [[X:%.*]]) {
+; NOLDEXP-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[ITOFP]])
+; NOLDEXP-NEXT:    ret float [[EXP2]]
+;
+  %itofp = uitofp i32 %x to float
+  %pow = tail call float @llvm.pow.f32(float 2.000000e+00, float %itofp)
+  ret float %pow
+}
+
+define float @pow_sitofp_f32_const_base_4(i32 %x) {
+; LDEXP-EXP2-LABEL: define float @pow_sitofp_f32_const_base_4(
+; LDEXP-EXP2-SAME: i32 [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
+; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 2.000000e+00
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
+; LDEXP-EXP2-NEXT:    ret float [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define float @pow_sitofp_f32_const_base_4(
+; LDEXP-NOEXP2-SAME: i32 [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 4.000000e+00, float [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret float [[POW]]
+;
+; NOLDEXP-LABEL: define float @pow_sitofp_f32_const_base_4(
+; NOLDEXP-SAME: i32 [[X:%.*]]) {
+; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
+; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 2.000000e+00
+; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
+; NOLDEXP-NEXT:    ret float [[EXP2]]
+;
+  %itofp = sitofp i32 %x to float
+  %pow = tail call float @llvm.pow.f32(float 4.000000e+00, float %itofp)
+  ret float %pow
+}
+
+define float @pow_sitofp_f32_const_base_16(i32 %x) {
+; LDEXP-EXP2-LABEL: define float @pow_sitofp_f32_const_base_16(
+; LDEXP-EXP2-SAME: i32 [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
+; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 4.000000e+00
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
+; LDEXP-EXP2-NEXT:    ret float [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define float @pow_sitofp_f32_const_base_16(
+; LDEXP-NOEXP2-SAME: i32 [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call float @llvm.pow.f32(float 1.600000e+01, float [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret float [[POW]]
+;
+; NOLDEXP-LABEL: define float @pow_sitofp_f32_const_base_16(
+; NOLDEXP-SAME: i32 [[X:%.*]]) {
+; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to float
+; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul float [[ITOFP]], 4.000000e+00
+; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call float @llvm.exp2.f32(float [[MUL]])
+; NOLDEXP-NEXT:    ret float [[EXP2]]
+;
+  %itofp = sitofp i32 %x to float
+  %pow = tail call float @llvm.pow.f32(float 16.000000e+00, float %itofp)
+  ret float %pow
+}
+
+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]]
+;
+  %itofp = sitofp i32 %x to double
+  %pow = tail call double @llvm.pow.f64(double 2.000000e+00, double %itofp)
+  ret double %pow
+}
+
+define half @pow_sitofp_f16_const_base_2(i32 %x) {
+; CHECK-LABEL: define half @pow_sitofp_f16_const_base_2(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = sitofp i32 [[X]] to half
+; CHECK-NEXT:    [[POW:%.*]] = tail call half @llvm.pow.f16(half 0xH4000, half [[ITOFP]])
+; CHECK-NEXT:    ret half [[POW]]
+;
+  %itofp = sitofp i32 %x to half
+  %pow = tail call half @llvm.pow.f16(half 2.000000e+00, half %itofp)
+  ret half %pow
+}
+
+define <2 x float> @pow_sitofp_v2f32_const_base_2(<2 x i32> %x) {
+; LDEXP-EXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i32> [[X]])
+; LDEXP-EXP2-NEXT:    ret <2 x float> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
+; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret <2 x float> [[POW]]
+;
+; 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]]
+;
+  %itofp = sitofp <2 x i32> %x to <2 x float>
+  %pow = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> %itofp)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @pow_sitofp_v2f32_const_base_8(<2 x i32> %x) {
+; LDEXP-EXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_8(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
+; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[ITOFP]], <float 3.000000e+00, float 3.000000e+00>
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
+; LDEXP-EXP2-NEXT:    ret <2 x float> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_8(
+; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 8.000000e+00, float 8.000000e+00>, <2 x float> [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret <2 x float> [[POW]]
+;
+; NOLDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_8(
+; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
+; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
+; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul <2 x float> [[ITOFP]], <float 3.000000e+00, float 3.000000e+00>
+; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call <2 x float> @llvm.exp2.v2f32(<2 x float> [[MUL]])
+; NOLDEXP-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> <float 8.000000e+00, float 8.000000e+00>, <2 x float> %itofp)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @pow_sitofp_v2f32_const_base_mixed_2(<2 x i32> %x) {
+; CHECK-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_mixed_2(
+; CHECK-SAME: <2 x i32> [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
+; CHECK-NEXT:    [[POW:%.*]] = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 4.000000e+00>, <2 x float> [[ITOFP]])
+; CHECK-NEXT:    ret <2 x float> [[POW]]
+;
+  %itofp = sitofp <2 x i32> %x to <2 x float>
+  %pow = tail call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 4.000000e+00>, <2 x float> %itofp)
+  ret <2 x float> %pow
+}
+
+define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(<2 x i32> %x) {
+; LDEXP-EXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call nsz afn <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i32> [[X]])
+; LDEXP-EXP2-NEXT:    ret <2 x float> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
+; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call nsz afn <2 x float> @llvm.powi.v2f32.v2i32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x i32> [[X]])
+; LDEXP-NOEXP2-NEXT:    ret <2 x float> [[POW]]
+;
+; 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]]
+;
+  %itofp = sitofp <2 x i32> %x to <2 x float>
+  %pow = tail call nsz afn <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> %itofp)
+  ret <2 x float> %pow
+}
+
+define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(<vscale x 4 x i32> %x) {
+; LDEXP-EXP2-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
+; LDEXP-EXP2-SAME: <vscale x 4 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <vscale x 4 x float> @llvm.ldexp.nxv4f32.nxv4i32(<vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 1.000000e+00, i64 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x i32> [[X]])
+; LDEXP-EXP2-NEXT:    ret <vscale x 4 x float> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
+; LDEXP-NOEXP2-SAME: <vscale x 4 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <vscale x 4 x i32> [[X]] to <vscale x 4 x float>
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <vscale x 4 x float> @llvm.pow.nxv4f32(<vscale x 4 x float> shufflevector (<vscale x 4 x float> insertelement (<vscale x 4 x float> poison, float 2.000000e+00, i64 0), <vscale x 4 x float> poison, <vscale x 4 x i32> zeroinitializer), <vscale x 4 x float> [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret <vscale x 4 x float> [[POW]]
+;
+; NOLDEXP-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
+; NOLDEXP-SAME: <vscale x 4 x i32> [[X:%.*]]) {
+; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp <vscale x 4 x i32> [[X]] to <vscale x 4 x float>
+; NOLDEXP-NEXT:    [[POW:%.*]] = tail call <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> [[ITOFP]])
+; NOLDEXP-NEXT:    ret <vscale x 4 x float> [[POW]]
+;
+  %itofp = sitofp <vscale x 4 x i32> %x to <vscale x 4 x float>
+  %pow = tail call <vscale x 4 x float> @llvm.pow.nxv4f32(<vscale x 4 x float> splat (float 2.0), <vscale x 4 x float> %itofp)
+  ret <vscale x 4 x float> %pow
+}
+
+define <2 x half> @pow_sitofp_v2f16_const_base_2(<2 x i32> %x) {
+; LDEXP-EXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.ldexp.v2f16.v2i32(<2 x half> <half 0xH3C00, half 0xH3C00>, <2 x i32> [[X]])
+; LDEXP-EXP2-NEXT:    ret <2 x half> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
+; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x half> @llvm.pow.v2f16(<2 x half> <half 0xH4000, half 0xH4000>, <2 x half> [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret <2 x half> [[POW]]
+;
+; 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]]
+;
+  %itofp = sitofp <2 x i32> %x to <2 x half>
+  %pow = tail call <2 x half> @llvm.pow.v2f16(<2 x half> <half 2.000000e+00, half 2.000000e+00>, <2 x half> %itofp)
+  ret <2 x half> %pow
+}
+
+define <2 x double> @pow_sitofp_v2f64_const_base_2(<2 x i32> %x) {
+; LDEXP-EXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x i32> [[X]])
+; LDEXP-EXP2-NEXT:    ret <2 x double> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
+; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret <2 x double> [[POW]]
+;
+; 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]]
+;
+  %itofp = sitofp <2 x i32> %x to <2 x double>
+  %pow = tail call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> %itofp)
+  ret <2 x double> %pow
+}
+
+define <2 x half> @pow_sitofp_v2f16_const_base_8(<2 x i32> %x) {
+; EXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
+; EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
+; EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x half> [[ITOFP]], <half 0xH4200, half 0xH4200>
+; EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[MUL]])
+; EXP2-NEXT:    ret <2 x half> [[EXP2]]
+;
+; LDEXP-EXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
+; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x half> [[ITOFP]], <half 0xH4200, half 0xH4200>
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[MUL]])
+; LDEXP-EXP2-NEXT:    ret <2 x half> [[EXP2]]
+;
+; LDEXP-NOEXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
+; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-NOEXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
+; LDEXP-NOEXP2-NEXT:    [[POW:%.*]] = tail call <2 x half> @llvm.pow.v2f16(<2 x half> <half 0xH4800, half 0xH4800>, <2 x half> [[ITOFP]])
+; LDEXP-NOEXP2-NEXT:    ret <2 x half> [[POW]]
+;
+; NOLDEXP-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_8(
+; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
+; NOLDEXP-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
+; NOLDEXP-NEXT:    [[MUL:%.*]] = fmul <2 x half> [[ITOFP]], <half 0xH4200, half 0xH4200>
+; NOLDEXP-NEXT:    [[EXP2:%.*]] = tail call <2 x half> @llvm.exp2.v2f16(<2 x half> [[MUL]])
+; NOLDEXP-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> <half 8.000000e+00, half 8.000000e+00>, <2 x half> %itofp)
+  ret <2 x half> %pow
+}
+
+define <2 x double> @pow_sitofp_v2f64_const_base_8(<2 x i32> %x) {
+; EXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_8(
+; EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
+; EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[ITOFP]], <double 3.000000e+00, double 3.000000e+00>
+; EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.exp2.v2f64(<2 x double> [[MUL]])
+; EXP2-NEXT:    ret <2 x double> [[EXP2]]
+;
+; LDEXP-EXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_8(
+; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
+; LDEXP-EXP2-NEXT:    [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
+; LDEXP-EXP2-NEXT:    [[MUL:%.*]] = fmul <2 x double> [[ITOFP]], <double 3.000000e+00, double 3.000000e+00>
+; LDEXP-EXP2-NEXT:    [[EXP2:%.*]] = tail call <2 x double> @llvm.exp2.v2f64(<2 x double>...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/92363


More information about the llvm-commits mailing list