summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorDavid Bolvansky <david.bolvansky@gmail.com>2019-07-10 14:43:27 +0000
committerDavid Bolvansky <david.bolvansky@gmail.com>2019-07-10 14:43:27 +0000
commit0735cc1954d84afa742abadf78e4136489f7cd0d (patch)
tree34b46971f5c62bb14fd7ec7df7166e5542b6f988 /llvm/test/Transforms
parent9cd82a4fbd2ded1e4d6b3815d153b28057ee1e75 (diff)
downloadbcm5719-llvm-0735cc1954d84afa742abadf78e4136489f7cd0d.tar.gz
bcm5719-llvm-0735cc1954d84afa742abadf78e4136489f7cd0d.zip
[InstCombine] pow(C,x) -> exp2(log2(C)*x)
Summary: Transform pow(C,x) To exp2(log2(C)*x) if C > 0, C != inf, C != NaN (and C is not power of 2, since we have some fold for such case already). log(C) is folded by the compiler and exp2 is much faster to compute than pow. Reviewers: spatel, efriedma, evandro Reviewed By: evandro Subscribers: lebedev.ri, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D64099 llvm-svn: 365637
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/InstCombine/pow-exp.ll49
-rw-r--r--llvm/test/Transforms/InstCombine/pow_fp_int.ll15
2 files changed, 40 insertions, 24 deletions
diff --git a/llvm/test/Transforms/InstCombine/pow-exp.ll b/llvm/test/Transforms/InstCombine/pow-exp.ll
index 9bc871cfc1e..d5ed5111781 100644
--- a/llvm/test/Transforms/InstCombine/pow-exp.ll
+++ b/llvm/test/Transforms/InstCombine/pow-exp.ll
@@ -205,13 +205,16 @@ define double @function_pointer(double ()* %fptr, double %p1) {
ret double %pow
}
+; pow(C,x) -> exp2(log2(C)*x)
+
declare void @use_d(double)
declare void @use_f(float)
define double @pow_ok_base(double %e) {
; CHECK-LABEL: @pow_ok_base(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @pow(double 0x3FE6666666666666, double [[E:%.*]])
-; CHECK-NEXT: ret double [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0xBFE0776228967D13
+; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf afn double @exp2(double [[MUL]])
+; CHECK-NEXT: ret double [[EXP2]]
;
%call = tail call afn nnan ninf double @pow(double 0x3FE6666666666666, double %e)
ret double %call
@@ -219,8 +222,9 @@ define double @pow_ok_base(double %e) {
define double @pow_ok_base_fast(double %e) {
; CHECK-LABEL: @pow_ok_base_fast(
-; CHECK-NEXT: [[CALL:%.*]] = tail call fast double @pow(double 0x3FE6666666666666, double [[E:%.*]])
-; CHECK-NEXT: ret double [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast double [[E:%.*]], 0xBFE0776228967D13
+; CHECK-NEXT: [[EXP2:%.*]] = call fast double @exp2(double [[MUL]])
+; CHECK-NEXT: ret double [[EXP2]]
;
%call = tail call fast double @pow(double 0x3FE6666666666666, double %e)
ret double %call
@@ -228,8 +232,9 @@ define double @pow_ok_base_fast(double %e) {
define double @pow_ok_base2(double %e) {
; CHECK-LABEL: @pow_ok_base2(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @pow(double 1.770000e+01, double [[E:%.*]])
-; CHECK-NEXT: ret double [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0x4010952C788751AC
+; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf afn double @exp2(double [[MUL]])
+; CHECK-NEXT: ret double [[EXP2]]
;
%call = tail call afn nnan ninf double @pow(double 1.770000e+01, double %e)
ret double %call
@@ -237,8 +242,9 @@ define double @pow_ok_base2(double %e) {
define double @pow_ok_base3(double %e) {
; CHECK-LABEL: @pow_ok_base3(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @pow(double 1.010000e+01, double [[E:%.*]])
-; CHECK-NEXT: ret double [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0x400AB0B5584886CD
+; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf afn double @exp2(double [[MUL]])
+; CHECK-NEXT: ret double [[EXP2]]
;
%call = tail call afn nnan ninf double @pow(double 1.010000e+01, double %e)
ret double %call
@@ -246,8 +252,9 @@ define double @pow_ok_base3(double %e) {
define double @pow_ok_ten_base(double %e) {
; CHECK-LABEL: @pow_ok_ten_base(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @pow(double 1.000000e+01, double [[E:%.*]])
-; CHECK-NEXT: ret double [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn double [[E:%.*]], 0x400A934F0979A371
+; CHECK-NEXT: [[EXP2:%.*]] = call nnan ninf afn double @exp2(double [[MUL]])
+; CHECK-NEXT: ret double [[EXP2]]
;
%call = tail call afn nnan ninf double @pow(double 1.000000e+01, double %e)
ret double %call
@@ -255,8 +262,9 @@ define double @pow_ok_ten_base(double %e) {
define float @powf_ok_base(float %e) {
; CHECK-LABEL: @powf_ok_base(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @powf(float 0x3FE6666660000000, float [[E:%.*]])
-; CHECK-NEXT: ret float [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0xBFE0776240000000
+; CHECK-NEXT: [[EXP2F:%.*]] = call nnan ninf afn float @exp2f(float [[MUL]])
+; CHECK-NEXT: ret float [[EXP2F]]
;
%call = tail call afn nnan ninf float @powf(float 0x3FE6666660000000, float %e)
ret float %call
@@ -264,8 +272,9 @@ define float @powf_ok_base(float %e) {
define float @powf_ok_base2(float %e) {
; CHECK-LABEL: @powf_ok_base2(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @powf(float 0x4031B33340000000, float [[E:%.*]])
-; CHECK-NEXT: ret float [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0x4010952C80000000
+; CHECK-NEXT: [[EXP2F:%.*]] = call nnan ninf afn float @exp2f(float [[MUL]])
+; CHECK-NEXT: ret float [[EXP2F]]
;
%call = tail call afn nnan ninf float @powf(float 0x4031B33340000000, float %e)
ret float %call
@@ -273,8 +282,9 @@ define float @powf_ok_base2(float %e) {
define float @powf_ok_base3(float %e) {
; CHECK-LABEL: @powf_ok_base3(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @powf(float 0x4024333340000000, float [[E:%.*]])
-; CHECK-NEXT: ret float [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0x400AB0B560000000
+; CHECK-NEXT: [[EXP2F:%.*]] = call nnan ninf afn float @exp2f(float [[MUL]])
+; CHECK-NEXT: ret float [[EXP2F]]
;
%call = tail call afn nnan ninf float @powf(float 0x4024333340000000, float %e)
ret float %call
@@ -282,13 +292,16 @@ define float @powf_ok_base3(float %e) {
define float @powf_ok_ten_base(float %e) {
; CHECK-LABEL: @powf_ok_ten_base(
-; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn float @powf(float 1.000000e+01, float [[E:%.*]])
-; CHECK-NEXT: ret float [[CALL]]
+; CHECK-NEXT: [[MUL:%.*]] = fmul nnan ninf afn float [[E:%.*]], 0x400A934F00000000
+; CHECK-NEXT: [[EXP2F:%.*]] = call nnan ninf afn float @exp2f(float [[MUL]])
+; CHECK-NEXT: ret float [[EXP2F]]
;
%call = tail call afn nnan ninf float @powf(float 1.000000e+01, float %e)
ret float %call
}
+; Negative tests
+
define double @pow_zero_base(double %e) {
; CHECK-LABEL: @pow_zero_base(
; CHECK-NEXT: [[CALL:%.*]] = tail call nnan ninf afn double @pow(double 0.000000e+00, double [[E:%.*]])
diff --git a/llvm/test/Transforms/InstCombine/pow_fp_int.ll b/llvm/test/Transforms/InstCombine/pow_fp_int.ll
index ff5ac896073..f89353cd707 100644
--- a/llvm/test/Transforms/InstCombine/pow_fp_int.ll
+++ b/llvm/test/Transforms/InstCombine/pow_fp_int.ll
@@ -196,8 +196,9 @@ define double @powf_exp_const2_int_fast(double %base) {
define double @pow_uitofp_const_base_fast_i32(i32 %x) {
; CHECK-LABEL: @pow_uitofp_const_base_fast_i32(
; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i32 [[X:%.*]] to float
-; CHECK-NEXT: [[POW:%.*]] = tail call fast float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
-; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
+; CHECK-NEXT: [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
+; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
; CHECK-NEXT: ret double [[RES]]
;
%subfp = uitofp i32 %x to float
@@ -247,8 +248,9 @@ define double @pow_uitofp_double_base_fast_i32(double %base, i32 %x) {
define double @pow_sitofp_const_base_fast_i64(i64 %x) {
; CHECK-LABEL: @pow_sitofp_const_base_fast_i64(
; CHECK-NEXT: [[SUBFP:%.*]] = sitofp i64 [[X:%.*]] to float
-; CHECK-NEXT: [[POW:%.*]] = tail call fast float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
-; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
+; CHECK-NEXT: [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
+; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
; CHECK-NEXT: ret double [[RES]]
;
%subfp = sitofp i64 %x to float
@@ -260,8 +262,9 @@ define double @pow_sitofp_const_base_fast_i64(i64 %x) {
define double @pow_uitofp_const_base_fast_i64(i64 %x) {
; CHECK-LABEL: @pow_uitofp_const_base_fast_i64(
; CHECK-NEXT: [[SUBFP:%.*]] = uitofp i64 [[X:%.*]] to float
-; CHECK-NEXT: [[POW:%.*]] = tail call fast float @llvm.pow.f32(float 7.000000e+00, float [[SUBFP]])
-; CHECK-NEXT: [[RES:%.*]] = fpext float [[POW]] to double
+; CHECK-NEXT: [[MUL:%.*]] = fmul fast float [[SUBFP]], 0x4006757680000000
+; CHECK-NEXT: [[EXP2:%.*]] = call fast float @llvm.exp2.f32(float [[MUL]])
+; CHECK-NEXT: [[RES:%.*]] = fpext float [[EXP2]] to double
; CHECK-NEXT: ret double [[RES]]
;
%subfp = uitofp i64 %x to float
OpenPOWER on IntegriCloud