[llvm] [InstCombine] Pre-commit tests for exp2(uitofp) -> ldexp with ninf. NFC (PR #227377)

Harrison Hao via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 01:12:20 PDT 2026


https://github.com/harrisonGPU updated https://github.com/llvm/llvm-project/pull/227377

>From 047e19dcabd5a13b78880fff15ba0a7d6ca8221f Mon Sep 17 00:00:00 2001
From: Harrison Hao <tsworld1314 at gmail.com>
Date: Tue, 29 Sep 2026 23:49:12 +0800
Subject: [PATCH] [InstCombine] Pre-commit tests for exp2(uitofp) -> ldexp with
 ninf. NFC

Add baseline tests for folding `exp2(uitofp iN x)` to `ldexp(1.0, x)`
when N equals the width of C int, including negative tests (no ninf,
source wider than int, libcall).
---
 llvm/test/Transforms/InstCombine/exp2-1.ll    | 137 +++++++++++-
 .../Transforms/InstCombine/exp2-to-ldexp.ll   | 196 ++++++++++++++++++
 2 files changed, 330 insertions(+), 3 deletions(-)

diff --git a/llvm/test/Transforms/InstCombine/exp2-1.ll b/llvm/test/Transforms/InstCombine/exp2-1.ll
index f924eaaddde8d..2369bc4f8c447 100644
--- a/llvm/test/Transforms/InstCombine/exp2-1.ll
+++ b/llvm/test/Transforms/InstCombine/exp2-1.ll
@@ -277,6 +277,137 @@ define float @test_simplify10(i8 zeroext %x) {
   ret float %ret
 }
 
+; ninf libcall must not fold: exp2f overflow sets errno.
+define float @test_readonly_exp2f_f32_of_uitofp_flags(i32 %x) {
+; LDEXP32-LABEL: @test_readonly_exp2f_f32_of_uitofp_flags(
+; LDEXP32-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to float
+; LDEXP32-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2:[0-9]+]]
+; LDEXP32-NEXT:    ret float [[RET]]
+;
+; LDEXP16-LABEL: @test_readonly_exp2f_f32_of_uitofp_flags(
+; LDEXP16-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2:[0-9]+]]
+; LDEXP16-NEXT:    ret float [[RET]]
+;
+; NOLDEXPF-LABEL: @test_readonly_exp2f_f32_of_uitofp_flags(
+; NOLDEXPF-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR2:[0-9]+]]
+; NOLDEXPF-NEXT:    ret float [[RET]]
+;
+; NOLDEXP-LABEL: @test_readonly_exp2f_f32_of_uitofp_flags(
+; NOLDEXP-NEXT:    [[CONV:%.*]] = uitofp i32 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[RET:%.*]] = call nnan ninf float @exp2f(float [[CONV]]) #[[ATTR1:[0-9]+]]
+; NOLDEXP-NEXT:    ret float [[RET]]
+;
+  %conv = uitofp i32 %x to float
+  %ret = call nnan ninf float @exp2f(float %conv) readonly
+  ret float %ret
+}
+
+define float @uitofp_i32_scalar_intrinsic_with_ninf(i32 %x) {
+; LDEXP32-LABEL: @uitofp_i32_scalar_intrinsic_with_ninf(
+; LDEXP32-NEXT:    [[U:%.*]] = uitofp i32 [[X:%.*]] to float
+; LDEXP32-NEXT:    [[R:%.*]] = tail call ninf float @llvm.exp2.f32(float [[U]])
+; LDEXP32-NEXT:    ret float [[R]]
+;
+; LDEXP16-LABEL: @uitofp_i32_scalar_intrinsic_with_ninf(
+; LDEXP16-NEXT:    [[U:%.*]] = uitofp i32 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[R:%.*]] = tail call ninf float @llvm.exp2.f32(float [[U]])
+; LDEXP16-NEXT:    ret float [[R]]
+;
+; NOLDEXPF-LABEL: @uitofp_i32_scalar_intrinsic_with_ninf(
+; NOLDEXPF-NEXT:    [[U:%.*]] = uitofp i32 [[X:%.*]] to float
+; NOLDEXPF-NEXT:    [[R:%.*]] = tail call ninf float @llvm.exp2.f32(float [[U]])
+; NOLDEXPF-NEXT:    ret float [[R]]
+;
+; NOLDEXP-LABEL: @uitofp_i32_scalar_intrinsic_with_ninf(
+; NOLDEXP-NEXT:    [[U:%.*]] = uitofp i32 [[X:%.*]] to float
+; NOLDEXP-NEXT:    [[R:%.*]] = tail call ninf float @llvm.exp2.f32(float [[U]])
+; NOLDEXP-NEXT:    ret float [[R]]
+;
+  %u = uitofp i32 %x to float
+  %r = tail call ninf float @llvm.exp2.f32(float %u)
+  ret float %r
+}
+
+define float @uitofp_i16_scalar_intrinsic_with_ninf(i16 %x) {
+; LDEXP32-LABEL: @uitofp_i16_scalar_intrinsic_with_ninf(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[R:%.*]] = tail call ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret float [[R]]
+;
+; LDEXP16-LABEL: @uitofp_i16_scalar_intrinsic_with_ninf(
+; LDEXP16-NEXT:    [[U:%.*]] = uitofp i16 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[R:%.*]] = tail call ninf float @llvm.exp2.f32(float [[U]])
+; LDEXP16-NEXT:    ret float [[R]]
+;
+; NOLDEXPF-LABEL: @uitofp_i16_scalar_intrinsic_with_ninf(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[R:%.*]] = tail call ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret float [[R]]
+;
+; NOLDEXP-LABEL: @uitofp_i16_scalar_intrinsic_with_ninf(
+; NOLDEXP-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXP-NEXT:    [[R:%.*]] = tail call ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; NOLDEXP-NEXT:    ret float [[R]]
+;
+  %u = uitofp i16 %x to float
+  %r = tail call ninf float @llvm.exp2.f32(float %u)
+  ret float %r
+}
+
+define float @uitofp_i16_scalar_intrinsic(i16 %x) {
+; LDEXP32-LABEL: @uitofp_i16_scalar_intrinsic(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[R:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret float [[R]]
+;
+; LDEXP16-LABEL: @uitofp_i16_scalar_intrinsic(
+; LDEXP16-NEXT:    [[U:%.*]] = uitofp i16 [[X:%.*]] to float
+; LDEXP16-NEXT:    [[R:%.*]] = tail call float @llvm.exp2.f32(float [[U]])
+; LDEXP16-NEXT:    ret float [[R]]
+;
+; NOLDEXPF-LABEL: @uitofp_i16_scalar_intrinsic(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[R:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret float [[R]]
+;
+; NOLDEXP-LABEL: @uitofp_i16_scalar_intrinsic(
+; NOLDEXP-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXP-NEXT:    [[R:%.*]] = tail call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
+; NOLDEXP-NEXT:    ret float [[R]]
+;
+  %u = uitofp i16 %x to float
+  %r = tail call float @llvm.exp2.f32(float %u)
+  ret float %r
+}
+
+define fp128 @uitofp_i16_scalar_intrinsic_fp128(i16 %x) {
+; LDEXP32-LABEL: @uitofp_i16_scalar_intrinsic_fp128(
+; LDEXP32-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; LDEXP32-NEXT:    [[R:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 1.000000e+00, i32 [[TMP1]])
+; LDEXP32-NEXT:    ret fp128 [[R]]
+;
+; LDEXP16-LABEL: @uitofp_i16_scalar_intrinsic_fp128(
+; LDEXP16-NEXT:    [[U:%.*]] = uitofp i16 [[X:%.*]] to fp128
+; LDEXP16-NEXT:    [[R:%.*]] = tail call fp128 @llvm.exp2.f128(fp128 [[U]])
+; LDEXP16-NEXT:    ret fp128 [[R]]
+;
+; NOLDEXPF-LABEL: @uitofp_i16_scalar_intrinsic_fp128(
+; NOLDEXPF-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXPF-NEXT:    [[R:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 1.000000e+00, i32 [[TMP1]])
+; NOLDEXPF-NEXT:    ret fp128 [[R]]
+;
+; NOLDEXP-LABEL: @uitofp_i16_scalar_intrinsic_fp128(
+; NOLDEXP-NEXT:    [[TMP1:%.*]] = zext i16 [[X:%.*]] to i32
+; NOLDEXP-NEXT:    [[R:%.*]] = tail call fp128 @llvm.ldexp.f128.i32(fp128 1.000000e+00, i32 [[TMP1]])
+; NOLDEXP-NEXT:    ret fp128 [[R]]
+;
+  %u = uitofp i16 %x to fp128
+  %r = tail call fp128 @llvm.exp2.f128(fp128 %u)
+  ret fp128 %r
+}
+
 define float @sitofp_scalar_intrinsic_with_FMF(i8 %x) {
 ; LDEXP32-LABEL: @sitofp_scalar_intrinsic_with_FMF(
 ; LDEXP32-NEXT:    [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
@@ -339,7 +470,7 @@ define double @test_readonly_exp2_f64_of_sitofp(i32 %x) {
 ;
 ; 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:%.*]] = call double @exp2(double [[CONV]]) #[[ATTR2]]
 ; LDEXP16-NEXT:    ret double [[RET]]
 ;
 ; NOLDEXPF-LABEL: @test_readonly_exp2_f64_of_sitofp(
@@ -348,7 +479,7 @@ define double @test_readonly_exp2_f64_of_sitofp(i32 %x) {
 ;
 ; 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:%.*]] = call double @exp2(double [[CONV]]) #[[ATTR1]]
 ; NOLDEXP-NEXT:    ret double [[RET]]
 ;
   %conv = sitofp i32 %x to double
@@ -368,7 +499,7 @@ define float @test_readonly_exp2f_f32_of_sitofp(i32 %x) {
 ;
 ; 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:%.*]] = call float @exp2f(float [[CONV]]) #[[ATTR2]]
 ; NOLDEXPF-NEXT:    ret float [[RET]]
 ;
 ; NOLDEXP-LABEL: @test_readonly_exp2f_f32_of_sitofp(
diff --git a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
index b47d2cc5d92a3..6acd1590a9e51 100644
--- a/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
+++ b/llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll
@@ -98,6 +98,202 @@ define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(<vscale x 4 x i8> %x) {
   ret <vscale x 4 x float> %exp2
 }
 
+; exp2(uitofp i32 x) -> ldexp(1.0, x) is only valid with ninf.
+
+define float @exp2_f32_uitofp_i32_ninf(i32 %x) {
+; CHECK-LABEL: define float @exp2_f32_uitofp_i32_ninf(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf float @llvm.exp2.f32(float [[ITOFP]])
+; CHECK-NEXT:    ret float [[EXP2]]
+;
+  %itofp = uitofp i32 %x to float
+  %exp2 = call ninf float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+define float @exp2_f32_uitofp_i32_flags(i32 %x) {
+; CHECK-LABEL: define float @exp2_f32_uitofp_i32_flags(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; CHECK-NEXT:    [[EXP2:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[ITOFP]])
+; CHECK-NEXT:    ret float [[EXP2]]
+;
+  %itofp = uitofp i32 %x to float
+  %exp2 = call nnan ninf float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+define <2 x float> @exp2_v2f32_uitofp_v2i32_ninf(<2 x i32> %x) {
+; CHECK-LABEL: define <2 x float> @exp2_v2f32_uitofp_v2i32_ninf(
+; CHECK-SAME: <2 x i32> [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp <2 x i32> [[X]] to <2 x float>
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf <2 x float> @llvm.exp2.v2f32(<2 x float> [[ITOFP]])
+; CHECK-NEXT:    ret <2 x float> [[EXP2]]
+;
+  %itofp = uitofp <2 x i32> %x to <2 x float>
+  %exp2 = call ninf <2 x float> @llvm.exp2.v2f32(<2 x float> %itofp)
+  ret <2 x float> %exp2
+}
+
+define <vscale x 4 x float> @exp2_nxv4f32_uitofp_i32_ninf(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: define <vscale x 4 x float> @exp2_nxv4f32_uitofp_i32_ninf(
+; CHECK-SAME: <vscale x 4 x i32> [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp <vscale x 4 x i32> [[X]] to <vscale x 4 x float>
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> [[ITOFP]])
+; CHECK-NEXT:    ret <vscale x 4 x float> [[EXP2]]
+;
+  %itofp = uitofp <vscale x 4 x i32> %x to <vscale x 4 x float>
+  %exp2 = call ninf <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> %itofp)
+  ret <vscale x 4 x float> %exp2
+}
+
+define half @exp2_f16_uitofp_i32_ninf(i32 %x) {
+; CHECK-LABEL: define half @exp2_f16_uitofp_i32_ninf(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to half
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf half @llvm.exp2.f16(half [[ITOFP]])
+; CHECK-NEXT:    ret half [[EXP2]]
+;
+  %itofp = uitofp i32 %x to half
+  %exp2 = call ninf half @llvm.exp2.f16(half %itofp)
+  ret half %exp2
+}
+
+define double @exp2_f64_uitofp_i32_ninf(i32 %x) {
+; CHECK-LABEL: define double @exp2_f64_uitofp_i32_ninf(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf double @llvm.exp2.f64(double [[ITOFP]])
+; CHECK-NEXT:    ret double [[EXP2]]
+;
+  %itofp = uitofp i32 %x to double
+  %exp2 = call ninf double @llvm.exp2.f64(double %itofp)
+  ret double %exp2
+}
+
+define fp128 @exp2_fp128_uitofp_i32_ninf(i32 %x) {
+; CHECK-LABEL: define fp128 @exp2_fp128_uitofp_i32_ninf(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to fp128
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf fp128 @llvm.exp2.f128(fp128 [[ITOFP]])
+; CHECK-NEXT:    ret fp128 [[EXP2]]
+;
+  %itofp = uitofp i32 %x to fp128
+  %exp2 = call ninf fp128 @llvm.exp2.fp128(fp128 %itofp)
+  ret fp128 %exp2
+}
+
+; Negative tests
+
+define float @exp2_f32_uitofp_i32(i32 %x) {
+; CHECK-LABEL: define float @exp2_f32_uitofp_i32(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; CHECK-NEXT:    [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[ITOFP]])
+; CHECK-NEXT:    ret float [[EXP2]]
+;
+  %itofp = uitofp i32 %x to float
+  %exp2 = call float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+define float @exp2_f32_uitofp_i32_nnan(i32 %x) {
+; CHECK-LABEL: define float @exp2_f32_uitofp_i32_nnan(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to float
+; CHECK-NEXT:    [[EXP2:%.*]] = call nnan float @llvm.exp2.f32(float [[ITOFP]])
+; CHECK-NEXT:    ret float [[EXP2]]
+;
+  %itofp = uitofp i32 %x to float
+  %exp2 = call nnan float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
+define <2 x float> @exp2_v2f32_uitofp_v2i32(<2 x i32> %x) {
+; CHECK-LABEL: define <2 x float> @exp2_v2f32_uitofp_v2i32(
+; CHECK-SAME: <2 x i32> [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp <2 x i32> [[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 = uitofp <2 x i32> %x to <2 x float>
+  %exp2 = call <2 x float> @llvm.exp2.v2f32(<2 x float> %itofp)
+  ret <2 x float> %exp2
+}
+
+define <vscale x 4 x float> @exp2_nxv4f32_uitofp_i32(<vscale x 4 x i32> %x) {
+; CHECK-LABEL: define <vscale x 4 x float> @exp2_nxv4f32_uitofp_i32(
+; CHECK-SAME: <vscale x 4 x i32> [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp <vscale x 4 x i32> [[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 = uitofp <vscale x 4 x i32> %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
+}
+
+define half @exp2_f16_uitofp_i32(i32 %x) {
+; CHECK-LABEL: define half @exp2_f16_uitofp_i32(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to half
+; CHECK-NEXT:    [[EXP2:%.*]] = call half @llvm.exp2.f16(half [[ITOFP]])
+; CHECK-NEXT:    ret half [[EXP2]]
+;
+  %itofp = uitofp i32 %x to half
+  %exp2 = call half @llvm.exp2.f16(half %itofp)
+  ret half %exp2
+}
+
+define double @exp2_f64_uitofp_i32(i32 %x) {
+; CHECK-LABEL: define double @exp2_f64_uitofp_i32(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to double
+; CHECK-NEXT:    [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[ITOFP]])
+; CHECK-NEXT:    ret double [[EXP2]]
+;
+  %itofp = uitofp i32 %x to double
+  %exp2 = call double @llvm.exp2.f64(double %itofp)
+  ret double %exp2
+}
+
+define fp128 @exp2_fp128_uitofp_i32(i32 %x) {
+; CHECK-LABEL: define fp128 @exp2_fp128_uitofp_i32(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to fp128
+; CHECK-NEXT:    [[EXP2:%.*]] = call fp128 @llvm.exp2.f128(fp128 [[ITOFP]])
+; CHECK-NEXT:    ret fp128 [[EXP2]]
+;
+  %itofp = uitofp i32 %x to fp128
+  %exp2 = call fp128 @llvm.exp2.fp128(fp128 %itofp)
+  ret fp128 %exp2
+}
+
+define ppc_fp128 @exp2_ppcf128_uitofp_i32(i32 %x) {
+; CHECK-LABEL: define ppc_fp128 @exp2_ppcf128_uitofp_i32(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i32 [[X]] to ppc_fp128
+; CHECK-NEXT:    [[EXP2:%.*]] = call ppc_fp128 @llvm.exp2.ppcf128(ppc_fp128 [[ITOFP]])
+; CHECK-NEXT:    ret ppc_fp128 [[EXP2]]
+;
+  %itofp = uitofp i32 %x to ppc_fp128
+  %exp2 = call ppc_fp128 @llvm.exp2.ppcf128(ppc_fp128 %itofp)
+  ret ppc_fp128 %exp2
+}
+
+define float @exp2_f32_uitofp_i64_ninf(i64 %x) {
+; CHECK-LABEL: define float @exp2_f32_uitofp_i64_ninf(
+; CHECK-SAME: i64 [[X:%.*]]) {
+; CHECK-NEXT:    [[ITOFP:%.*]] = uitofp i64 [[X]] to float
+; CHECK-NEXT:    [[EXP2:%.*]] = call ninf float @llvm.exp2.f32(float [[ITOFP]])
+; CHECK-NEXT:    ret float [[EXP2]]
+;
+  %itofp = uitofp i64 %x to float
+  %exp2 = call ninf float @llvm.exp2.f32(float %itofp)
+  ret float %exp2
+}
+
 ; FIXME: This asserts
 ; define bfloat @exp2_bf16_sitofp_i8(i8 %x) {
 ;   %itofp = sitofp i8 %x to bfloat



More information about the llvm-commits mailing list