Skip to content

Commit c1c1567

Browse files
authored
SimplifyLibCalls: Permit pow(2, x) -> ldexp(1, x) fold for vectors (#92532)
1 parent eab92cb commit c1c1567

File tree

2 files changed

+24
-52
lines changed

2 files changed

+24
-52
lines changed

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,15 +2087,16 @@ Value *LibCallSimplifier::replacePowWithExp(CallInst *Pow, IRBuilderBase &B) {
20872087

20882088
AttributeList NoAttrs; // Attributes are only meaningful on the original call
20892089

2090+
const bool UseIntrinsic = Pow->doesNotAccessMemory();
2091+
20902092
// pow(2.0, itofp(x)) -> ldexp(1.0, x)
2091-
// TODO: This does not work for vectors because there is no ldexp intrinsic.
2092-
if (!Ty->isVectorTy() && match(Base, m_SpecificFP(2.0)) &&
2093+
if ((UseIntrinsic || !Ty->isVectorTy()) && match(Base, m_SpecificFP(2.0)) &&
20932094
(isa<SIToFPInst>(Expo) || isa<UIToFPInst>(Expo)) &&
20942095
hasFloatFn(M, TLI, Ty, LibFunc_ldexp, LibFunc_ldexpf, LibFunc_ldexpl)) {
20952096
if (Value *ExpoI = getIntToFPVal(Expo, B, TLI->getIntSize())) {
20962097
Constant *One = ConstantFP::get(Ty, 1.0);
20972098

2098-
if (Pow->doesNotAccessMemory()) {
2099+
if (UseIntrinsic) {
20992100
return copyFlags(*Pow, B.CreateIntrinsic(Intrinsic::ldexp,
21002101
{Ty, ExpoI->getType()},
21012102
{One, ExpoI}, Pow, "exp2"));

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

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,10 @@ define half @pow_sitofp_f16_const_base_2(i32 %x) {
144144
}
145145

146146
define <2 x float> @pow_sitofp_v2f32_const_base_2(<2 x i32> %x) {
147-
; LDEXP-EXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
148-
; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
149-
; 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]])
150-
; LDEXP-EXP2-NEXT: ret <2 x float> [[EXP2]]
151-
;
152-
; LDEXP-NOEXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
153-
; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
154-
; LDEXP-NOEXP2-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x float>
155-
; 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]])
156-
; LDEXP-NOEXP2-NEXT: ret <2 x float> [[POW]]
147+
; LDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
148+
; LDEXP-SAME: <2 x i32> [[X:%.*]]) {
149+
; LDEXP-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]])
150+
; LDEXP-NEXT: ret <2 x float> [[EXP2]]
157151
;
158152
; NOLDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2(
159153
; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
@@ -205,15 +199,10 @@ define <2 x float> @pow_sitofp_v2f32_const_base_mixed_2(<2 x i32> %x) {
205199
}
206200

207201
define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(<2 x i32> %x) {
208-
; LDEXP-EXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
209-
; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
210-
; 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]])
211-
; LDEXP-EXP2-NEXT: ret <2 x float> [[EXP2]]
212-
;
213-
; LDEXP-NOEXP2-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
214-
; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
215-
; 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]])
216-
; LDEXP-NOEXP2-NEXT: ret <2 x float> [[POW]]
202+
; LDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
203+
; LDEXP-SAME: <2 x i32> [[X:%.*]]) {
204+
; LDEXP-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]])
205+
; LDEXP-NEXT: ret <2 x float> [[EXP2]]
217206
;
218207
; NOLDEXP-LABEL: define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(
219208
; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
@@ -227,16 +216,10 @@ define <2 x float> @pow_sitofp_v2f32_const_base_2__flags(<2 x i32> %x) {
227216
}
228217

229218
define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(<vscale x 4 x i32> %x) {
230-
; LDEXP-EXP2-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
231-
; LDEXP-EXP2-SAME: <vscale x 4 x i32> [[X:%.*]]) {
232-
; 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]])
233-
; LDEXP-EXP2-NEXT: ret <vscale x 4 x float> [[EXP2]]
234-
;
235-
; LDEXP-NOEXP2-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
236-
; LDEXP-NOEXP2-SAME: <vscale x 4 x i32> [[X:%.*]]) {
237-
; LDEXP-NOEXP2-NEXT: [[ITOFP:%.*]] = sitofp <vscale x 4 x i32> [[X]] to <vscale x 4 x float>
238-
; 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]])
239-
; LDEXP-NOEXP2-NEXT: ret <vscale x 4 x float> [[POW]]
219+
; LDEXP-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
220+
; LDEXP-SAME: <vscale x 4 x i32> [[X:%.*]]) {
221+
; LDEXP-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]])
222+
; LDEXP-NEXT: ret <vscale x 4 x float> [[EXP2]]
240223
;
241224
; NOLDEXP-LABEL: define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(
242225
; NOLDEXP-SAME: <vscale x 4 x i32> [[X:%.*]]) {
@@ -250,16 +233,10 @@ define <vscale x 4 x float> @pow_sitofp_nxv4f32_const_base_2(<vscale x 4 x i32>
250233
}
251234

252235
define <2 x half> @pow_sitofp_v2f16_const_base_2(<2 x i32> %x) {
253-
; LDEXP-EXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
254-
; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
255-
; LDEXP-EXP2-NEXT: [[EXP2:%.*]] = tail call <2 x half> @llvm.ldexp.v2f16.v2i32(<2 x half> <half 0xH3C00, half 0xH3C00>, <2 x i32> [[X]])
256-
; LDEXP-EXP2-NEXT: ret <2 x half> [[EXP2]]
257-
;
258-
; LDEXP-NOEXP2-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
259-
; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
260-
; LDEXP-NOEXP2-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x half>
261-
; LDEXP-NOEXP2-NEXT: [[POW:%.*]] = tail call <2 x half> @llvm.pow.v2f16(<2 x half> <half 0xH4000, half 0xH4000>, <2 x half> [[ITOFP]])
262-
; LDEXP-NOEXP2-NEXT: ret <2 x half> [[POW]]
236+
; LDEXP-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
237+
; LDEXP-SAME: <2 x i32> [[X:%.*]]) {
238+
; LDEXP-NEXT: [[EXP2:%.*]] = tail call <2 x half> @llvm.ldexp.v2f16.v2i32(<2 x half> <half 0xH3C00, half 0xH3C00>, <2 x i32> [[X]])
239+
; LDEXP-NEXT: ret <2 x half> [[EXP2]]
263240
;
264241
; NOLDEXP-LABEL: define <2 x half> @pow_sitofp_v2f16_const_base_2(
265242
; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {
@@ -273,16 +250,10 @@ define <2 x half> @pow_sitofp_v2f16_const_base_2(<2 x i32> %x) {
273250
}
274251

275252
define <2 x double> @pow_sitofp_v2f64_const_base_2(<2 x i32> %x) {
276-
; LDEXP-EXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
277-
; LDEXP-EXP2-SAME: <2 x i32> [[X:%.*]]) {
278-
; 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]])
279-
; LDEXP-EXP2-NEXT: ret <2 x double> [[EXP2]]
280-
;
281-
; LDEXP-NOEXP2-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
282-
; LDEXP-NOEXP2-SAME: <2 x i32> [[X:%.*]]) {
283-
; LDEXP-NOEXP2-NEXT: [[ITOFP:%.*]] = sitofp <2 x i32> [[X]] to <2 x double>
284-
; 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]])
285-
; LDEXP-NOEXP2-NEXT: ret <2 x double> [[POW]]
253+
; LDEXP-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
254+
; LDEXP-SAME: <2 x i32> [[X:%.*]]) {
255+
; LDEXP-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]])
256+
; LDEXP-NEXT: ret <2 x double> [[EXP2]]
286257
;
287258
; NOLDEXP-LABEL: define <2 x double> @pow_sitofp_v2f64_const_base_2(
288259
; NOLDEXP-SAME: <2 x i32> [[X:%.*]]) {

0 commit comments

Comments
 (0)