Skip to content

Commit 8788b66

Browse files
authored
SimplifyLibCalls: Don't require ldexp to emit intrinsic in exp2 combine (#92707)
When folding exp2(itofp(x)) to ldexp(1, x), don't require an ldexp libcall to emit the intrinsic. The intrinsic needs to be handled regardless of whether the system has a libcall, and we have an inline implementation of ldexp already. This fixes the instance in the exp2->ldexp fold. Another instance exists for the pow(2) -> ldexp case The LTO test change isn't ideal, since it's just moving the problem to another instance where we're relying on implied libm behavior for an intrinsic transform. Use exp10 since that's a harder case to solve in the libcall house of cards we have.
1 parent d63ade6 commit 8788b66

File tree

5 files changed

+118
-223
lines changed

5 files changed

+118
-223
lines changed

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2376,7 +2376,13 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
23762376
hasFloatVersion(M, Name))
23772377
Ret = optimizeUnaryDoubleFP(CI, B, TLI, true);
23782378

2379-
const bool UseIntrinsic = CI->doesNotAccessMemory();
2379+
// If we have an llvm.exp2 intrinsic, emit the llvm.ldexp intrinsic. If we
2380+
// have the libcall, emit the libcall.
2381+
//
2382+
// TODO: In principle we should be able to just always use the intrinsic for
2383+
// any doesNotAccessMemory callsite.
2384+
2385+
const bool UseIntrinsic = Callee->isIntrinsic();
23802386
// Bail out for vectors because the code below only expects scalars.
23812387
Type *Ty = CI->getType();
23822388
if (!UseIntrinsic && Ty->isVectorTy())
@@ -2386,12 +2392,11 @@ Value *LibCallSimplifier::optimizeExp2(CallInst *CI, IRBuilderBase &B) {
23862392
// exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < IntSize
23872393
Value *Op = CI->getArgOperand(0);
23882394
if ((isa<SIToFPInst>(Op) || isa<UIToFPInst>(Op)) &&
2389-
hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
2395+
(UseIntrinsic ||
2396+
hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl))) {
23902397
if (Value *Exp = getIntToFPVal(Op, B, TLI->getIntSize())) {
23912398
Constant *One = ConstantFP::get(Ty, 1.0);
23922399

2393-
// TODO: Emitting the intrinsic should not depend on whether the libcall
2394-
// is available.
23952400
if (UseIntrinsic) {
23962401
return copyFlags(*CI, B.CreateIntrinsic(Intrinsic::ldexp,
23972402
{Ty, Exp->getType()},

llvm/test/LTO/X86/triple-init2.ll

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,20 @@
1111
; RUN: llvm-lto2 run -r %t1,main,plx -o %t2 %t1
1212
; RUN: llvm-nm %t2.1 | FileCheck %s
1313

14-
; We check that LTO will be aware of target triple and prevent exp2 to ldexpf
14+
; We check that LTO will be aware of target triple and prevent pow to exp10
1515
; transformation on Windows.
16-
; CHECK: U exp2f
16+
; CHECK: U powf
1717

1818
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
1919
target triple = "x86_64-pc-windows-msvc19.11.0"
2020

21+
declare float @llvm.pow.f32(float, float)
22+
2123
define dso_local i32 @main(i32 %argc, ptr nocapture readnone %argv) local_unnamed_addr {
2224
entry:
2325
%conv = sitofp i32 %argc to float
24-
%exp2 = tail call float @llvm.exp2.f32(float %conv)
26+
%exp2 = tail call float @llvm.pow.f32(float 10.0, float %conv)
2527
%conv1 = fptosi float %exp2 to i32
2628
ret i32 %conv1
2729
}
2830

29-
; Function Attrs: nounwind readnone speculatable
30-
declare float @llvm.exp2.f32(float)
31-

llvm/test/Transforms/InstCombine/exp2-1.ll

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ define double @test_simplify9(i8 zeroext %x) {
242242
; NOLDEXPF-NEXT: ret double [[RET]]
243243
;
244244
; NOLDEXP-LABEL: @test_simplify9(
245-
; NOLDEXP-NEXT: [[CONV:%.*]] = uitofp i8 [[X:%.*]] to double
246-
; NOLDEXP-NEXT: [[RET:%.*]] = call double @llvm.exp2.f64(double [[CONV]])
245+
; NOLDEXP-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
246+
; NOLDEXP-NEXT: [[RET:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
247247
; NOLDEXP-NEXT: ret double [[RET]]
248248
;
249249
%conv = uitofp i8 %x to double
@@ -263,13 +263,13 @@ define float @test_simplify10(i8 zeroext %x) {
263263
; LDEXP16-NEXT: ret float [[RET]]
264264
;
265265
; NOLDEXPF-LABEL: @test_simplify10(
266-
; NOLDEXPF-NEXT: [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
267-
; NOLDEXPF-NEXT: [[RET:%.*]] = call float @llvm.exp2.f32(float [[CONV]])
266+
; NOLDEXPF-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
267+
; NOLDEXPF-NEXT: [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
268268
; NOLDEXPF-NEXT: ret float [[RET]]
269269
;
270270
; NOLDEXP-LABEL: @test_simplify10(
271-
; NOLDEXP-NEXT: [[CONV:%.*]] = uitofp i8 [[X:%.*]] to float
272-
; NOLDEXP-NEXT: [[RET:%.*]] = call float @llvm.exp2.f32(float [[CONV]])
271+
; NOLDEXP-NEXT: [[TMP1:%.*]] = zext i8 [[X:%.*]] to i32
272+
; NOLDEXP-NEXT: [[RET:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
273273
; NOLDEXP-NEXT: ret float [[RET]]
274274
;
275275
%conv = uitofp i8 %x to float
@@ -289,13 +289,13 @@ define float @sitofp_scalar_intrinsic_with_FMF(i8 %x) {
289289
; LDEXP16-NEXT: ret float [[R]]
290290
;
291291
; NOLDEXPF-LABEL: @sitofp_scalar_intrinsic_with_FMF(
292-
; NOLDEXPF-NEXT: [[S:%.*]] = sitofp i8 [[X:%.*]] to float
293-
; NOLDEXPF-NEXT: [[R:%.*]] = tail call nnan float @llvm.exp2.f32(float [[S]])
292+
; NOLDEXPF-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
293+
; NOLDEXPF-NEXT: [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
294294
; NOLDEXPF-NEXT: ret float [[R]]
295295
;
296296
; NOLDEXP-LABEL: @sitofp_scalar_intrinsic_with_FMF(
297-
; NOLDEXP-NEXT: [[S:%.*]] = sitofp i8 [[X:%.*]] to float
298-
; NOLDEXP-NEXT: [[R:%.*]] = tail call nnan float @llvm.exp2.f32(float [[S]])
297+
; NOLDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X:%.*]] to i32
298+
; NOLDEXP-NEXT: [[R:%.*]] = tail call nnan float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
299299
; NOLDEXP-NEXT: ret float [[R]]
300300
;
301301
%s = sitofp i8 %x to float
@@ -317,9 +317,14 @@ define <2 x float> @sitofp_vector_intrinsic_with_FMF(<2 x i8> %x) {
317317
; LDEXP16-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i16(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i16> [[TMP1]])
318318
; LDEXP16-NEXT: ret <2 x float> [[R]]
319319
;
320+
; NOLDEXPF-LABEL: @sitofp_vector_intrinsic_with_FMF(
321+
; NOLDEXPF-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
322+
; NOLDEXPF-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i32> [[TMP1]])
323+
; NOLDEXPF-NEXT: ret <2 x float> [[R]]
324+
;
320325
; NOLDEXP-LABEL: @sitofp_vector_intrinsic_with_FMF(
321-
; NOLDEXP-NEXT: [[S:%.*]] = sitofp <2 x i8> [[X:%.*]] to <2 x float>
322-
; NOLDEXP-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.exp2.v2f32(<2 x float> [[S]])
326+
; NOLDEXP-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X:%.*]] to <2 x i32>
327+
; NOLDEXP-NEXT: [[R:%.*]] = call nnan <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i32> [[TMP1]])
323328
; NOLDEXP-NEXT: ret <2 x float> [[R]]
324329
;
325330
%s = sitofp <2 x i8> %x to <2 x float>

llvm/test/Transforms/InstCombine/exp2-to-ldexp.ll

Lines changed: 39 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,49 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2-
; RUN: opt -S -passes=instcombine %s | FileCheck -check-prefixes=CHECK,LDEXP %s
3-
; RUN: opt -S -passes=instcombine -disable-builtin=ldexpf -disable-builtin=ldexp -disable-builtin=ldexpl %s | FileCheck -check-prefixes=CHECK,NOLDEXP %s
2+
; RUN: opt -S -passes=instcombine %s | FileCheck %s
3+
; RUN: opt -S -passes=instcombine -disable-builtin=ldexpf -disable-builtin=ldexp -disable-builtin=ldexpl %s | FileCheck %s
44

55
define float @exp2_f32_sitofp_i8(i8 %x) {
6-
; LDEXP-LABEL: define float @exp2_f32_sitofp_i8(
7-
; LDEXP-SAME: i8 [[X:%.*]]) {
8-
; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
9-
; LDEXP-NEXT: [[LDEXPF:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
10-
; LDEXP-NEXT: ret float [[LDEXPF]]
11-
;
12-
; NOLDEXP-LABEL: define float @exp2_f32_sitofp_i8(
13-
; NOLDEXP-SAME: i8 [[X:%.*]]) {
14-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to float
15-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[ITOFP]])
16-
; NOLDEXP-NEXT: ret float [[EXP2]]
6+
; CHECK-LABEL: define float @exp2_f32_sitofp_i8(
7+
; CHECK-SAME: i8 [[X:%.*]]) {
8+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
9+
; CHECK-NEXT: [[EXP2:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
10+
; CHECK-NEXT: ret float [[EXP2]]
1711
;
1812
%itofp = sitofp i8 %x to float
1913
%exp2 = call float @llvm.exp2.f32(float %itofp)
2014
ret float %exp2
2115
}
2216

2317
define float @exp2_f32_sitofp_i8_flags(i8 %x) {
24-
; LDEXP-LABEL: define float @exp2_f32_sitofp_i8_flags(
25-
; LDEXP-SAME: i8 [[X:%.*]]) {
26-
; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
27-
; LDEXP-NEXT: [[LDEXPF:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
28-
; LDEXP-NEXT: ret float [[LDEXPF]]
29-
;
30-
; NOLDEXP-LABEL: define float @exp2_f32_sitofp_i8_flags(
31-
; NOLDEXP-SAME: i8 [[X:%.*]]) {
32-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to float
33-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call nnan ninf float @llvm.exp2.f32(float [[ITOFP]])
34-
; NOLDEXP-NEXT: ret float [[EXP2]]
18+
; CHECK-LABEL: define float @exp2_f32_sitofp_i8_flags(
19+
; CHECK-SAME: i8 [[X:%.*]]) {
20+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
21+
; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
22+
; CHECK-NEXT: ret float [[EXP2]]
3523
;
3624
%itofp = sitofp i8 %x to float
3725
%exp2 = call nnan ninf float @llvm.exp2.f32(float %itofp)
3826
ret float %exp2
3927
}
4028

4129
define <2 x float> @exp2_v2f32_sitofp_v2i8(<2 x i8> %x) {
42-
; LDEXP-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8(
43-
; LDEXP-SAME: <2 x i8> [[X:%.*]]) {
44-
; LDEXP-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
45-
; LDEXP-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i32> [[TMP1]])
46-
; LDEXP-NEXT: ret <2 x float> [[EXP2]]
47-
;
48-
; NOLDEXP-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8(
49-
; NOLDEXP-SAME: <2 x i8> [[X:%.*]]) {
50-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <2 x i8> [[X]] to <2 x float>
51-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.exp2.v2f32(<2 x float> [[ITOFP]])
52-
; NOLDEXP-NEXT: ret <2 x float> [[EXP2]]
30+
; CHECK-LABEL: define <2 x float> @exp2_v2f32_sitofp_v2i8(
31+
; CHECK-SAME: <2 x i8> [[X:%.*]]) {
32+
; CHECK-NEXT: [[TMP1:%.*]] = sext <2 x i8> [[X]] to <2 x i32>
33+
; CHECK-NEXT: [[EXP2:%.*]] = call <2 x float> @llvm.ldexp.v2f32.v2i32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x i32> [[TMP1]])
34+
; CHECK-NEXT: ret <2 x float> [[EXP2]]
5335
;
5436
%itofp = sitofp <2 x i8> %x to <2 x float>
5537
%exp2 = call <2 x float> @llvm.exp2.v2f32(<2 x float> %itofp)
5638
ret <2 x float> %exp2
5739
}
5840

5941
define float @exp2_f32_uitofp_i8(i8 %x) {
60-
; LDEXP-LABEL: define float @exp2_f32_uitofp_i8(
61-
; LDEXP-SAME: i8 [[X:%.*]]) {
62-
; LDEXP-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i32
63-
; LDEXP-NEXT: [[LDEXPF:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
64-
; LDEXP-NEXT: ret float [[LDEXPF]]
65-
;
66-
; NOLDEXP-LABEL: define float @exp2_f32_uitofp_i8(
67-
; NOLDEXP-SAME: i8 [[X:%.*]]) {
68-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = uitofp i8 [[X]] to float
69-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call float @llvm.exp2.f32(float [[ITOFP]])
70-
; NOLDEXP-NEXT: ret float [[EXP2]]
42+
; CHECK-LABEL: define float @exp2_f32_uitofp_i8(
43+
; CHECK-SAME: i8 [[X:%.*]]) {
44+
; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[X]] to i32
45+
; CHECK-NEXT: [[EXP2:%.*]] = call float @llvm.ldexp.f32.i32(float 1.000000e+00, i32 [[TMP1]])
46+
; CHECK-NEXT: ret float [[EXP2]]
7147
;
7248
%itofp = uitofp i8 %x to float
7349
%exp2 = call float @llvm.exp2.f32(float %itofp)
@@ -77,8 +53,8 @@ define float @exp2_f32_uitofp_i8(i8 %x) {
7753
define half @exp2_f16_sitofp_i8(i8 %x) {
7854
; CHECK-LABEL: define half @exp2_f16_sitofp_i8(
7955
; CHECK-SAME: i8 [[X:%.*]]) {
80-
; CHECK-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to half
81-
; CHECK-NEXT: [[EXP2:%.*]] = call half @llvm.exp2.f16(half [[ITOFP]])
56+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
57+
; CHECK-NEXT: [[EXP2:%.*]] = call half @llvm.ldexp.f16.i32(half 0xH3C00, i32 [[TMP1]])
8258
; CHECK-NEXT: ret half [[EXP2]]
8359
;
8460
%itofp = sitofp i8 %x to half
@@ -87,53 +63,35 @@ define half @exp2_f16_sitofp_i8(i8 %x) {
8763
}
8864

8965
define double @exp2_f64_sitofp_i8(i8 %x) {
90-
; LDEXP-LABEL: define double @exp2_f64_sitofp_i8(
91-
; LDEXP-SAME: i8 [[X:%.*]]) {
92-
; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
93-
; LDEXP-NEXT: [[LDEXP:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
94-
; LDEXP-NEXT: ret double [[LDEXP]]
95-
;
96-
; NOLDEXP-LABEL: define double @exp2_f64_sitofp_i8(
97-
; NOLDEXP-SAME: i8 [[X:%.*]]) {
98-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to double
99-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call double @llvm.exp2.f64(double [[ITOFP]])
100-
; NOLDEXP-NEXT: ret double [[EXP2]]
66+
; CHECK-LABEL: define double @exp2_f64_sitofp_i8(
67+
; CHECK-SAME: i8 [[X:%.*]]) {
68+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
69+
; CHECK-NEXT: [[EXP2:%.*]] = call double @llvm.ldexp.f64.i32(double 1.000000e+00, i32 [[TMP1]])
70+
; CHECK-NEXT: ret double [[EXP2]]
10171
;
10272
%itofp = sitofp i8 %x to double
10373
%exp2 = call double @llvm.exp2.f64(double %itofp)
10474
ret double %exp2
10575
}
10676

10777
define fp128 @exp2_fp128_sitofp_i8(i8 %x) {
108-
; LDEXP-LABEL: define fp128 @exp2_fp128_sitofp_i8(
109-
; LDEXP-SAME: i8 [[X:%.*]]) {
110-
; LDEXP-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
111-
; LDEXP-NEXT: [[LDEXPL:%.*]] = call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]])
112-
; LDEXP-NEXT: ret fp128 [[LDEXPL]]
113-
;
114-
; NOLDEXP-LABEL: define fp128 @exp2_fp128_sitofp_i8(
115-
; NOLDEXP-SAME: i8 [[X:%.*]]) {
116-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp i8 [[X]] to fp128
117-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call fp128 @llvm.exp2.f128(fp128 [[ITOFP]])
118-
; NOLDEXP-NEXT: ret fp128 [[EXP2]]
78+
; CHECK-LABEL: define fp128 @exp2_fp128_sitofp_i8(
79+
; CHECK-SAME: i8 [[X:%.*]]) {
80+
; CHECK-NEXT: [[TMP1:%.*]] = sext i8 [[X]] to i32
81+
; CHECK-NEXT: [[EXP2:%.*]] = call fp128 @llvm.ldexp.f128.i32(fp128 0xL00000000000000003FFF000000000000, i32 [[TMP1]])
82+
; CHECK-NEXT: ret fp128 [[EXP2]]
11983
;
12084
%itofp = sitofp i8 %x to fp128
12185
%exp2 = call fp128 @llvm.exp2.fp128(fp128 %itofp)
12286
ret fp128 %exp2
12387
}
12488

12589
define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(<vscale x 4 x i8> %x) {
126-
; LDEXP-LABEL: define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(
127-
; LDEXP-SAME: <vscale x 4 x i8> [[X:%.*]]) {
128-
; LDEXP-NEXT: [[TMP1:%.*]] = sext <vscale x 4 x i8> [[X]] to <vscale x 4 x i32>
129-
; LDEXP-NEXT: [[EXP2:%.*]] = 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> [[TMP1]])
130-
; LDEXP-NEXT: ret <vscale x 4 x float> [[EXP2]]
131-
;
132-
; NOLDEXP-LABEL: define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(
133-
; NOLDEXP-SAME: <vscale x 4 x i8> [[X:%.*]]) {
134-
; NOLDEXP-NEXT: [[ITOFP:%.*]] = sitofp <vscale x 4 x i8> [[X]] to <vscale x 4 x float>
135-
; NOLDEXP-NEXT: [[EXP2:%.*]] = call <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> [[ITOFP]])
136-
; NOLDEXP-NEXT: ret <vscale x 4 x float> [[EXP2]]
90+
; CHECK-LABEL: define <vscale x 4 x float> @exp2_nxv4f32_sitofp_i8(
91+
; CHECK-SAME: <vscale x 4 x i8> [[X:%.*]]) {
92+
; CHECK-NEXT: [[TMP1:%.*]] = sext <vscale x 4 x i8> [[X]] to <vscale x 4 x i32>
93+
; CHECK-NEXT: [[EXP2:%.*]] = 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> [[TMP1]])
94+
; CHECK-NEXT: ret <vscale x 4 x float> [[EXP2]]
13795
;
13896
%itofp = sitofp <vscale x 4 x i8> %x to <vscale x 4 x float>
13997
%exp2 = call <vscale x 4 x float> @llvm.exp2.nxv4f32(<vscale x 4 x float> %itofp)

0 commit comments

Comments
 (0)