[llvm] InstCombine: Emit ldexp intrinsic in exp2->ldexp combine (PR #92039)

Matt Arsenault via llvm-commits llvm-commits at lists.llvm.org
Mon May 13 15:13:12 PDT 2024


https://github.com/arsenm created https://github.com/llvm/llvm-project/pull/92039

Prefer to emit the intrinsic over a libcall in the
intrinsic or no-math-errno case.

>From e7009474fbc3a7a2e6441acf8dae908c4b4ea065 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 13 May 2024 22:05:34 +0200
Subject: [PATCH 1/2] InstCombine: Add baseline tests for exp2 to ldexp
 transform

---
 llvm/test/Transforms/InstCombine/exp2-1.ll    |  95 ++++++++++++++
 .../Transforms/InstCombine/exp2-to-ldexp.ll   | 122 ++++++++++++++++++
 2 files changed, 217 insertions(+)
 create mode 100644 llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll

diff --git a/llvm/test/Transforms/InstCombine/exp2-1.ll b/llvm/test/Transforms/InstCombine/exp2-1.ll
index 8419854d3ec64..d4887a23acbee 100644
--- a/llvm/test/Transforms/InstCombine/exp2-1.ll
+++ b/llvm/test/Transforms/InstCombine/exp2-1.ll
@@ -14,6 +14,7 @@ declare float @exp2f(float)
 declare double @llvm.exp2.f64(double)
 declare float @llvm.exp2.f32(float)
 declare <2 x float> @llvm.exp2.v2f32(<2 x float>)
+declare fp128 @exp2l(fp128)
 
 
 ; Check exp2(sitofp(x)) -> ldexp(1.0, sext(x)).
@@ -330,3 +331,97 @@ define <2 x float> @sitofp_vector_intrinsic_with_FMF(<2 x i8> %x) {
   %r = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> %s)
   ret <2 x float> %r
 }
+
+define double @test_readonly_exp2_f64_of_sitofp(i32 %x) {
+; LDEXP32-LABEL: @test_readonly_exp2_f64_of_sitofp(
+; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
+; LDEXP32-NEXT:    ret double [[LDEXP]]
+;
+; LDEXP16-LABEL: @test_readonly_exp2_f64_of_sitofp(
+; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
+; LDEXP16-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]]) #[[ATTR2:[0-9]+]]
+; LDEXP16-NEXT:    ret double [[RET]]
+;
+; NOLDEXPF-LABEL: @test_readonly_exp2_f64_of_sitofp(
+; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[X:%.*]])
+; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+;
+; NOLDEXP-LABEL: @test_readonly_exp2_f64_of_sitofp(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to double
+; NOLDEXP-NEXT:    [[RET:%.*]] = call double @exp2(double [[CONV]]) #[[ATTR1:[0-9]+]]
+; NOLDEXP-NEXT:    ret double [[RET]]
+;
+  %conv = sitofp i32 %x to double
+  %ret = call double @exp2(double %conv) readonly
+  ret double %ret
+}
+
+define float @test_readonly_exp2f_f32_of_sitofp(i32 %x) {
+; LDEXP32-LABEL: @test_readonly_exp2f_f32_of_sitofp(
+; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
+; LDEXP32-NEXT:    ret float [[LDEXPF]]
+;
+; LDEXP16-LABEL: @test_readonly_exp2f_f32_of_sitofp(
+; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR2]]
+; LDEXP16-NEXT:    ret float [[RET]]
+;
+; NOLDEXPF-LABEL: @test_readonly_exp2f_f32_of_sitofp(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR2:[0-9]+]]
+; NOLDEXPF-NEXT:    ret float [[RET]]
+;
+; NOLDEXP-LABEL: @test_readonly_exp2f_f32_of_sitofp(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[RET:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR1]]
+; NOLDEXP-NEXT:    ret float [[RET]]
+;
+  %conv = sitofp i32 %x to float
+  %ret = call float @exp2f(float %conv) readonly
+  ret float %ret
+}
+
+define fp128 @test_readonly_exp2l_fp128_of_sitofp(i32 %x) {
+; LDEXP32-LABEL: @test_readonly_exp2l_fp128_of_sitofp(
+; LDEXP32-NEXT:    [[LDEXPL:%.*]] = call fp128 @ldexpl(fp128 0xL00000000000000003FFF000000000000, i32 [[X:%.*]])
+; LDEXP32-NEXT:    ret fp128 [[LDEXPL]]
+;
+; LDEXP16-LABEL: @test_readonly_exp2l_fp128_of_sitofp(
+; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to fp128
+; LDEXP16-NEXT:    [[RET:%.*]] = call fp128 @exp2l(fp128 [[CONV]]) #[[ATTR2]]
+; LDEXP16-NEXT:    ret fp128 [[RET]]
+;
+; NOLDEXP-LABEL: @test_readonly_exp2l_fp128_of_sitofp(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to fp128
+; NOLDEXP-NEXT:    [[RET:%.*]] = call fp128 @exp2l(fp128 [[CONV]]) #[[ATTR1]]
+; NOLDEXP-NEXT:    ret fp128 [[RET]]
+;
+  %conv = sitofp i32 %x to fp128
+  %ret = call fp128 @exp2l(fp128 %conv) readonly
+  ret fp128 %ret
+}
+
+define float @test_readonly_exp2f_f32_of_sitofp_flags(i32 %x) {
+; LDEXP32-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
+; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call nnan ninf float @ldexpf(float 1.000000e+00, i32 [[X:%.*]])
+; LDEXP32-NEXT:    ret float [[LDEXPF]]
+;
+; LDEXP16-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
+; LDEXP16-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2]]
+; LDEXP16-NEXT:    ret float [[RET]]
+;
+; NOLDEXPF-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2]]
+; NOLDEXPF-NEXT:    ret float [[RET]]
+;
+; NOLDEXP-LABEL: @test_readonly_exp2f_f32_of_sitofp_flags(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = sitofp i32 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR1]]
+; NOLDEXP-NEXT:    ret float [[RET]]
+;
+  %conv = sitofp i32 %x to float
+  %ret = call nnan ninf float @exp2f(float %conv) readonly
+  ret float %ret
+}
diff --git a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
new file mode 100644
index 0000000000000..3537373ef4d46
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
@@ -0,0 +1,122 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; Note: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt -S -passes=instcombine %s | FileCheck %s
+; xUN: opt -mtriple=aarch64-pc-linux-gnu -S -passes=instcombine %s | FileCheck -check-prefix=AARCH64 %s
+; xUN: opt -mtriple=amdgcn-amd-amdhsa -S -passes=instcombine %s | FileCheck -check-prefix=AMDGCN %s
+
+define float @exp2_f32_sitofp_i8(i8 %x) {
+; CHECK-LABEL: define float @exp2_f32_sitofp_i8(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    ret float [[LDEXPF]]
+;
+  %itofp = sitofp i8 %x to float
+  %exp2 = call float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+define float @exp2_f32_sitofp_i8_flags(i8 %x) {
+; CHECK-LABEL: define float @exp2_f32_sitofp_i8_flags(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[LDEXPF:%.*]] = call nnan ninf float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    ret float [[LDEXPF]]
+;
+  %itofp = sitofp i8 %x to float
+  %exp2 = call nnan ninf float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+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]]
+;
+  %itofp = sitofp <2 x i8> %x to <2 x float>
+  %exp2 = call <2 x float> @llvm.exp2.v2f32(<2 x float> %itofp)
+  ret <2 x float> %exp2
+}
+
+define float @exp2_f32_uitofp_i8(i8 %x) {
+; CHECK-LABEL: define float @exp2_f32_uitofp_i8(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X]] to i32
+; CHECK-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    ret float [[LDEXPF]]
+;
+  %itofp = uitofp i8 %x to float
+  %exp2 = call float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+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:    ret half [[EXP2]]
+;
+  %itofp = sitofp i8 %x to half
+  %exp2 = call half @llvm.exp2.f16(half %itofp)
+  ret half %exp2
+}
+
+define double @exp2_f64_sitofp_i8(i8 %x) {
+; CHECK-LABEL: define double @exp2_f64_sitofp_i8(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    ret double [[LDEXP]]
+;
+  %itofp = sitofp i8 %x to double
+  %exp2 = call double @llvm.exp2.f64(double %itofp)
+  ret double %exp2
+}
+
+define fp128 @exp2_fp128_sitofp_i8(i8 %x) {
+; CHECK-LABEL: define fp128 @exp2_fp128_sitofp_i8(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
+; CHECK-NEXT:    [[LDEXPL:%.*]] = call fp128 @ldexpl(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]])
+; CHECK-NEXT:    ret fp128 [[LDEXPL]]
+;
+  %itofp = sitofp i8 %x to fp128
+  %exp2 = call fp128 @llvm.exp2.fp128(fp128 %itofp)
+  ret fp128 %exp2
+}
+
+define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(<vscale x 4 x i8> %x) {
+; CHECK-LABEL: define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(
+; CHECK-SAME: <vscale x 4 x i8> [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = sitofp <vscale x 4 x i8> [[X]] to <vscale x 4 x float>
+; CHECK-NEXT:    [[EXP2:%.*]] = call <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> [[ITOFP]])
+; CHECK-NEXT:    ret <vscale x 4 x float> [[EXP2]]
+;
+  %itofp = sitofp <vscale x 4 x i8> %x to <vscale x 4 x float>
+  %exp2 = call <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> %itofp)
+  ret <vscale x 4 x float> %exp2
+}
+
+; FIXME: This asserts
+; define bfloat @exp2_bf16_sitofp_i8(i8 %x) {
+;   %itofp = sitofp i8 %x to bfloat
+;   %exp2 = call bfloat @llvm.exp2.bf16(bfloat %itofp)
+;   ret bfloat %exp2
+; }
+
+; FIXME: This asserts
+; define ppc_fp128 @exp2_ppc_fp128_sitofp_i8(i8 %x) {
+;   %itofp = sitofp i8 %x to ppc_fp128
+;   %exp2 = call ppc_fp128 @llvm.exp2.ppcf128(ppc_fp128 %itofp)
+;   ret ppc_fp128 %exp2
+; }
+
+; FIXME: This asserts
+; define x86_fp80 @exp2_x86_fp80_sitofp_i8(i8 %x) {
+;   %itofp = sitofp i8 %x to x86_fp80
+;   %exp2 = call x86_fp80 @llvm.exp2.f80(x86_fp80 %itofp)
+;   ret x86_fp80 %exp2
+; }

>From 368188423ea5914bdbcda8ae6652e36a411dd622 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <Matthew.Arsenault at amd.com>
Date: Mon, 13 May 2024 21:57:52 +0200
Subject: [PATCH 2/2] InstCombine: Emit ldexp intrinsic in exp2->ldexp combine

Prefer to emit the intrinsic over a libcall in the
intrinsic or no-math-errno case.
---
 .../lib/Transforms/Utils/SimplifyLibCalls.cpp | 17 ++++++++---
 llvm/test/Transforms/InstCombine/exp2-1.ll    | 28 +++++++++----------
 .../Transforms/InstCombine/exp2-to-ldexp.ll   | 10 +++----
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 174cc7a3c778d..9cb8e20b4806f 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2389,12 +2389,21 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
   if ((isa<SIToFPInst>(Op) || isa<UIToFPInst>(Op)) &&
       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 (CI->doesNotAccessMemory()) {
+        return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp,
+                                                {Ty, Exp->getType()},
+                                                {One, Exp}, CI));
+      }
+
       IRBuilderBase::FastMathFlagGuard Guard(B);
       B.setFastMathFlags(CI->getFastMathFlags());
-      return copyFlags(
-          *CI, emitBinaryFloatFnCall(ConstantFP::get(Ty, 1.0), Exp, TLI,
-                                     LibFunc_ldexp, LibFunc_ldexpf,
-                                     LibFunc_ldexpl, B, AttributeList()));
+      return copyFlags(*CI, emitBinaryFloatFnCall(
+                                One, Exp, TLI, LibFunc_ldexp, LibFunc_ldexpf,
+                                LibFunc_ldexpl, B, AttributeList()));
     }
   }
 
diff --git a/llvm/test/Transforms/InstCombine/exp2-1.ll b/llvm/test/Transforms/InstCombine/exp2-1.ll
index d4887a23acbee..5bf70320d9ec4 100644
--- a/llvm/test/Transforms/InstCombine/exp2-1.ll
+++ b/llvm/test/Transforms/InstCombine/exp2-1.ll
@@ -228,18 +228,18 @@ define float @test_simplify8(i8 zeroext %x) {
 define double @test_simplify9(i8 zeroext %x) {
 ; LDEXP32-LABEL: @test_simplify9(
 ; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
-; LDEXP32-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
-; LDEXP32-NEXT:    ret double [[LDEXP]]
+; LDEXP32-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret double [[RET]]
 ;
 ; LDEXP16-LABEL: @test_simplify9(
 ; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
-; LDEXP16-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i16 [[TMP1]])
-; LDEXP16-NEXT:    ret double [[LDEXP]]
+; LDEXP16-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i16(double 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret double [[RET]]
 ;
 ; NOLDEXPF-LABEL: @test_simplify9(
 ; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
-; NOLDEXPF-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
-; NOLDEXPF-NEXT:    ret double [[LDEXP]]
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret double [[RET]]
 ;
 ; NOLDEXP-LABEL: @test_simplify9(
 ; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to double
@@ -254,13 +254,13 @@ define double @test_simplify9(i8 zeroext %x) {
 define float @test_simplify10(i8 zeroext %x) {
 ; LDEXP32-LABEL: @test_simplify10(
 ; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
-; LDEXP32-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
-; LDEXP32-NEXT:    ret float [[LDEXPF]]
+; LDEXP32-NEXT:    [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret float [[RET]]
 ;
 ; LDEXP16-LABEL: @test_simplify10(
 ; LDEXP16-NEXT:    [[TMP1:%.*]] = zext i8 [[X:%.*]] to i16
-; LDEXP16-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i16 [[TMP1]])
-; LDEXP16-NEXT:    ret float [[LDEXPF]]
+; LDEXP16-NEXT:    [[RET:%.*]] = call float @llvm.ldexp.f32.i16(float 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret float [[RET]]
 ;
 ; NOLDEXPF-LABEL: @test_simplify10(
 ; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
@@ -280,13 +280,13 @@ define float @test_simplify10(i8 zeroext %x) {
 define float @sitofp_scalar_intrinsic_with_FMF(i8 %x) {
 ; LDEXP32-LABEL: @sitofp_scalar_intrinsic_with_FMF(
 ; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
-; LDEXP32-NEXT:    [[LDEXPF:%.*]] = tail call nnan float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
-; LDEXP32-NEXT:    ret float [[LDEXPF]]
+; LDEXP32-NEXT:    [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret float [[R]]
 ;
 ; LDEXP16-LABEL: @sitofp_scalar_intrinsic_with_FMF(
 ; LDEXP16-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i16
-; LDEXP16-NEXT:    [[LDEXPF:%.*]] = tail call nnan float @ldexpf(float 1.000000e+00, i16 [[TMP1]])
-; LDEXP16-NEXT:    ret float [[LDEXPF]]
+; LDEXP16-NEXT:    [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i16(float 1.000000e+00, i16 [[TMP1]])
+; LDEXP16-NEXT:    ret float [[R]]
 ;
 ; NOLDEXPF-LABEL: @sitofp_scalar_intrinsic_with_FMF(
 ; NOLDEXPF-NEXT:    [[S:%.*]] = sitofp i8 [[X:%.*]] to float
diff --git a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
index 3537373ef4d46..0763df5cb1067 100644
--- a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
+++ b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
@@ -8,7 +8,7 @@ define float @exp2_f32_sitofp_i8(i8 %x) {
 ; CHECK-LABEL: define float @exp2_f32_sitofp_i8(
 ; CHECK-SAME: i8 [[X:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
-; CHECK-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    [[LDEXPF:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
 ; CHECK-NEXT:    ret float [[LDEXPF]]
 ;
   %itofp = sitofp i8 %x to float
@@ -20,7 +20,7 @@ define float @exp2_f32_sitofp_i8_flags(i8 %x) {
 ; CHECK-LABEL: define float @exp2_f32_sitofp_i8_flags(
 ; CHECK-SAME: i8 [[X:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
-; CHECK-NEXT:    [[LDEXPF:%.*]] = call nnan ninf float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    [[LDEXPF:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
 ; CHECK-NEXT:    ret float [[LDEXPF]]
 ;
   %itofp = sitofp i8 %x to float
@@ -44,7 +44,7 @@ define float @exp2_f32_uitofp_i8(i8 %x) {
 ; CHECK-LABEL: define float @exp2_f32_uitofp_i8(
 ; CHECK-SAME: i8 [[X:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = zext i8 [[X]] to i32
-; CHECK-NEXT:    [[LDEXPF:%.*]] = call float @ldexpf(float 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    [[LDEXPF:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
 ; CHECK-NEXT:    ret float [[LDEXPF]]
 ;
   %itofp = uitofp i8 %x to float
@@ -68,7 +68,7 @@ define double @exp2_f64_sitofp_i8(i8 %x) {
 ; CHECK-LABEL: define double @exp2_f64_sitofp_i8(
 ; CHECK-SAME: i8 [[X:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
-; CHECK-NEXT:    [[LDEXP:%.*]] = call double @ldexp(double 1.000000e+00, i32 [[TMP1]])
+; CHECK-NEXT:    [[LDEXP:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
 ; CHECK-NEXT:    ret double [[LDEXP]]
 ;
   %itofp = sitofp i8 %x to double
@@ -80,7 +80,7 @@ define fp128 @exp2_fp128_sitofp_i8(i8 %x) {
 ; CHECK-LABEL: define fp128 @exp2_fp128_sitofp_i8(
 ; CHECK-SAME: i8 [[X:%.*]]) {
 ; CHECK-NEXT:    [[TMP1:%.*]] = sext i8 [[X]] to i32
-; CHECK-NEXT:    [[LDEXPL:%.*]] = call fp128 @ldexpl(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]])
+; CHECK-NEXT:    [[LDEXPL:%.*]] = call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]])
 ; CHECK-NEXT:    ret fp128 [[LDEXPL]]
 ;
   %itofp = sitofp i8 %x to fp128



More information about the llvm-commits mailing list