Skip to content

Commit e737847

Browse files
committed
[SLC] Allow llvm.pow(x,2.0) -> x*x etc even if no pow() lib func
optimizePow does not create any new calls to pow, so it should work regardless of whether the pow library function is available. This allows it to optimize the llvm.pow intrinsic on targets with no math library. Based on a patch by Tim Renouf. Differential Revision: https://reviews.llvm.org/D68231
1 parent 8e9a8dc commit e737847

File tree

3 files changed

+28
-67
lines changed

3 files changed

+28
-67
lines changed

llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,10 +1668,6 @@ Value *LibCallSimplifier::optimizePow(CallInst *Pow, IRBuilderBase &B) {
16681668
bool AllowApprox = Pow->hasApproxFunc();
16691669
bool Ignored;
16701670

1671-
// Bail out if simplifying libcalls to pow() is disabled.
1672-
if (!hasFloatFn(TLI, Ty, LibFunc_pow, LibFunc_powf, LibFunc_powl))
1673-
return nullptr;
1674-
16751671
// Propagate the math semantics from the call to any created instructions.
16761672
IRBuilderBase::FastMathFlagGuard Guard(B);
16771673
B.setFastMathFlags(Pow->getFastMathFlags());

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

Lines changed: 23 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,7 @@ define float @test_simplify1(float %x) {
4141

4242
define <2 x float> @test_simplify1v(<2 x float> %x) {
4343
; CHECK-LABEL: @test_simplify1v(
44-
; ANY-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
45-
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]])
46-
; MSVC-NEXT: ret <2 x float> [[POW]]
47-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.000000e+00, float 1.000000e+00>, <2 x float> [[X:%.*]])
48-
; NOLIB-NEXT: ret <2 x float> [[POW]]
44+
; CHECK-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
4945
;
5046
%retval = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 1.0, float 1.0>, <2 x float> %x)
5147
ret <2 x float> %retval
@@ -63,11 +59,7 @@ define double @test_simplify2(double %x) {
6359

6460
define <2 x double> @test_simplify2v(<2 x double> %x) {
6561
; CHECK-LABEL: @test_simplify2v(
66-
; ANY-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
67-
; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x double> [[X:%.*]])
68-
; MSVC-NEXT: ret <2 x double> [[POW]]
69-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.000000e+00, double 1.000000e+00>, <2 x double> [[X:%.*]])
70-
; NOLIB-NEXT: ret <2 x double> [[POW]]
62+
; CHECK-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
7163
;
7264
%retval = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 1.0, double 1.0>, <2 x double> %x)
7365
ret <2 x double> %retval
@@ -119,6 +111,7 @@ define <2 x float> @test_simplify3v(<2 x float> %x) {
119111
; ANY-NEXT: ret <2 x float> [[EXP2]]
120112
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]])
121113
; MSVC-NEXT: ret <2 x float> [[POW]]
114+
; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
122115
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 2.000000e+00, float 2.000000e+00>, <2 x float> [[X:%.*]])
123116
; NOLIB-NEXT: ret <2 x float> [[POW]]
124117
;
@@ -133,6 +126,7 @@ define <2 x double> @test_simplify3vn(<2 x double> %x) {
133126
; ANY-NEXT: ret <2 x double> [[EXP2]]
134127
; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]])
135128
; MSVC-NEXT: ret <2 x double> [[POW]]
129+
; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
136130
; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 4.000000e+00, double 4.000000e+00>, <2 x double> [[X:%.*]])
137131
; NOLIB-NEXT: ret <2 x double> [[POW]]
138132
;
@@ -184,6 +178,7 @@ define <2 x double> @test_simplify4v(<2 x double> %x) {
184178
; ANY-NEXT: ret <2 x double> [[EXP2]]
185179
; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]])
186180
; MSVC-NEXT: ret <2 x double> [[POW]]
181+
; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
187182
; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> <double 2.000000e+00, double 2.000000e+00>, <2 x double> [[X:%.*]])
188183
; NOLIB-NEXT: ret <2 x double> [[POW]]
189184
;
@@ -198,6 +193,7 @@ define <2 x float> @test_simplify4vn(<2 x float> %x) {
198193
; ANY-NEXT: ret <2 x float> [[EXP2]]
199194
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]])
200195
; MSVC-NEXT: ret <2 x float> [[POW]]
196+
; TODO: should be able to simplify llvm.pow to llvm.exp2 even without libcalls
201197
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> <float 5.000000e-01, float 5.000000e-01>, <2 x float> [[X:%.*]])
202198
; NOLIB-NEXT: ret <2 x float> [[POW]]
203199
;
@@ -225,11 +221,7 @@ define float @test_simplify5(float %x) {
225221

226222
define <2 x float> @test_simplify5v(<2 x float> %x) {
227223
; CHECK-LABEL: @test_simplify5v(
228-
; ANY-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
229-
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer)
230-
; MSVC-NEXT: ret <2 x float> [[POW]]
231-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> zeroinitializer)
232-
; NOLIB-NEXT: ret <2 x float> [[POW]]
224+
; CHECK-NEXT: ret <2 x float> <float 1.000000e+00, float 1.000000e+00>
233225
;
234226
%retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 0.0, float 0.0>)
235227
ret <2 x float> %retval
@@ -247,11 +239,7 @@ define double @test_simplify6(double %x) {
247239

248240
define <2 x double> @test_simplify6v(<2 x double> %x) {
249241
; CHECK-LABEL: @test_simplify6v(
250-
; ANY-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
251-
; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer)
252-
; MSVC-NEXT: ret <2 x double> [[POW]]
253-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> zeroinitializer)
254-
; NOLIB-NEXT: ret <2 x double> [[POW]]
242+
; CHECK-NEXT: ret <2 x double> <double 1.000000e+00, double 1.000000e+00>
255243
;
256244
%retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 0.0, double 0.0>)
257245
ret <2 x double> %retval
@@ -349,11 +337,7 @@ define float @test_simplify11(float %x) {
349337

350338
define <2 x float> @test_simplify11v(<2 x float> %x) {
351339
; CHECK-LABEL: @test_simplify11v(
352-
; ANY-NEXT: ret <2 x float> [[X:%.*]]
353-
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>)
354-
; MSVC-NEXT: ret <2 x float> [[POW]]
355-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 1.000000e+00, float 1.000000e+00>)
356-
; NOLIB-NEXT: ret <2 x float> [[POW]]
340+
; CHECK-NEXT: ret <2 x float> [[X:%.*]]
357341
;
358342
%retval = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 1.0, float 1.0>)
359343
ret <2 x float> %retval
@@ -371,11 +355,7 @@ define double @test_simplify12(double %x) {
371355

372356
define <2 x double> @test_simplify12v(<2 x double> %x) {
373357
; CHECK-LABEL: @test_simplify12v(
374-
; ANY-NEXT: ret <2 x double> [[X:%.*]]
375-
; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 1.000000e+00, double 1.000000e+00>)
376-
; MSVC-NEXT: ret <2 x double> [[POW]]
377-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 1.000000e+00, double 1.000000e+00>)
378-
; NOLIB-NEXT: ret <2 x double> [[POW]]
358+
; CHECK-NEXT: ret <2 x double> [[X:%.*]]
379359
;
380360
%retval = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 1.0, double 1.0>)
381361
ret <2 x double> %retval
@@ -404,12 +384,8 @@ define float @pow2_strict(float %x) {
404384

405385
define <2 x float> @pow2_strictv(<2 x float> %x) {
406386
; CHECK-LABEL: @pow2_strictv(
407-
; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]]
408-
; ANY-NEXT: ret <2 x float> [[SQUARE]]
409-
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 2.000000e+00, float 2.000000e+00>)
410-
; MSVC-NEXT: ret <2 x float> [[POW]]
411-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float 2.000000e+00, float 2.000000e+00>)
412-
; NOLIB-NEXT: ret <2 x float> [[POW]]
387+
; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x float> [[X:%.*]], [[X]]
388+
; CHECK-NEXT: ret <2 x float> [[SQUARE]]
413389
;
414390
%r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float 2.0, float 2.0>)
415391
ret <2 x float> %r
@@ -428,12 +404,8 @@ define double @pow2_double_strict(double %x) {
428404

429405
define <2 x double> @pow2_double_strictv(<2 x double> %x) {
430406
; CHECK-LABEL: @pow2_double_strictv(
431-
; ANY-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]]
432-
; ANY-NEXT: ret <2 x double> [[SQUARE]]
433-
; MSVC-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 2.000000e+00, double 2.000000e+00>)
434-
; MSVC-NEXT: ret <2 x double> [[POW]]
435-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double 2.000000e+00, double 2.000000e+00>)
436-
; NOLIB-NEXT: ret <2 x double> [[POW]]
407+
; CHECK-NEXT: [[SQUARE:%.*]] = fmul <2 x double> [[X:%.*]], [[X]]
408+
; CHECK-NEXT: ret <2 x double> [[SQUARE]]
437409
;
438410
%r = call <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.0, double 2.0>)
439411
ret <2 x double> %r
@@ -483,12 +455,8 @@ define float @pow_neg1_strict(float %x) {
483455

484456
define <2 x float> @pow_neg1_strictv(<2 x float> %x) {
485457
; CHECK-LABEL: @pow_neg1_strictv(
486-
; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X:%.*]]
487-
; ANY-NEXT: ret <2 x float> [[RECIPROCAL]]
488-
; MSVC-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float -1.000000e+00, float -1.000000e+00>)
489-
; MSVC-NEXT: ret <2 x float> [[POW]]
490-
; NOLIB-NEXT: [[POW:%.*]] = call <2 x float> @llvm.pow.v2f32(<2 x float> [[X:%.*]], <2 x float> <float -1.000000e+00, float -1.000000e+00>)
491-
; NOLIB-NEXT: ret <2 x float> [[POW]]
458+
; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, [[X:%.*]]
459+
; CHECK-NEXT: ret <2 x float> [[RECIPROCAL]]
492460
;
493461
%r = call <2 x float> @llvm.pow.v2f32(<2 x float> %x, <2 x float> <float -1.0, float -1.0>)
494462
ret <2 x float> %r
@@ -507,26 +475,20 @@ define double @pow_neg1_double_fast(double %x) {
507475

508476
define <2 x double> @pow_neg1_double_fastv(<2 x double> %x) {
509477
; CHECK-LABEL: @pow_neg1_double_fastv(
510-
; ANY-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X:%.*]]
511-
; ANY-NEXT: ret <2 x double> [[RECIPROCAL]]
512-
; MSVC-NEXT: [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double -1.000000e+00, double -1.000000e+00>)
513-
; MSVC-NEXT: ret <2 x double> [[POW]]
514-
; NOLIB-NEXT: [[POW:%.*]] = call fast <2 x double> @llvm.pow.v2f64(<2 x double> [[X:%.*]], <2 x double> <double -1.000000e+00, double -1.000000e+00>)
515-
; NOLIB-NEXT: ret <2 x double> [[POW]]
478+
; CHECK-NEXT: [[RECIPROCAL:%.*]] = fdiv fast <2 x double> <double 1.000000e+00, double 1.000000e+00>, [[X:%.*]]
479+
; CHECK-NEXT: ret <2 x double> [[RECIPROCAL]]
516480
;
517481
%r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double -1.0, double -1.0>)
518482
ret <2 x double> %r
519483
}
520484

521485
define double @test_simplify17(double %x) {
522486
; CHECK-LABEL: @test_simplify17(
523-
; LIB-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]])
524-
; LIB-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
525-
; LIB-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
526-
; LIB-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
527-
; LIB-NEXT: ret double [[TMP1]]
528-
; NOLIB-NEXT: [[POW:%.*]] = call double @llvm.pow.f64(double [[X:%.*]], double 5.000000e-01)
529-
; NOLIB-NEXT: ret double [[POW]]
487+
; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]])
488+
; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
489+
; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
490+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
491+
; CHECK-NEXT: ret double [[TMP1]]
530492
;
531493
%retval = call double @llvm.pow.f64(double %x, double 0.5)
532494
ret double %retval

llvm/test/Transforms/InstCombine/pow-3.ll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ define double @sqrt_libcall(double %x) {
1515

1616
define double @sqrt_intrinsic(double %x) {
1717
; CHECK-LABEL: @sqrt_intrinsic(
18-
; CHECK-NEXT: [[RETVAL:%.*]] = call double @llvm.pow.f64(double [[X:%.*]], double 5.000000e-01)
19-
; CHECK-NEXT: ret double [[RETVAL]]
18+
; CHECK-NEXT: [[SQRT:%.*]] = call double @llvm.sqrt.f64(double [[X:%.*]])
19+
; CHECK-NEXT: [[ABS:%.*]] = call double @llvm.fabs.f64(double [[SQRT]])
20+
; CHECK-NEXT: [[ISINF:%.*]] = fcmp oeq double [[X]], 0xFFF0000000000000
21+
; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[ISINF]], double 0x7FF0000000000000, double [[ABS]]
22+
; CHECK-NEXT: ret double [[TMP1]]
2023
;
2124
%retval = call double @llvm.pow.f64(double %x, double 0.5)
2225
ret double %retval

0 commit comments

Comments
 (0)