[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