summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMeador Inge <meadori@codesourcery.com>2012-11-13 04:16:17 +0000
committerMeador Inge <meadori@codesourcery.com>2012-11-13 04:16:17 +0000
commit2920a71663b96f2c33b1fee09ca5ca9f5dc1cf12 (patch)
treede057ca88e82ce75a40dc65a04b4d4db0db0a2ec /test
parent4712b804dfe02bc7bbf948f9a5e352b3f14cc89a (diff)
downloadllvm-2920a71663b96f2c33b1fee09ca5ca9f5dc1cf12.tar.gz
llvm-2920a71663b96f2c33b1fee09ca5ca9f5dc1cf12.tar.bz2
llvm-2920a71663b96f2c33b1fee09ca5ca9f5dc1cf12.tar.xz
instcombine: Migrate math library call simplifications
This patch migrates the math library call simplifications from the simplify-libcalls pass into the instcombine library call simplifier. I have typically migrated just one simplifier at a time, but the math simplifiers are interdependent because: 1. CosOpt, PowOpt, and Exp2Opt all depend on UnaryDoubleFPOpt. 2. CosOpt, PowOpt, Exp2Opt, and UnaryDoubleFPOpt all depend on the option -enable-double-float-shrink. These two factors made migrating each of these simplifiers individually more of a pain than it would be worth. So, I migrated them all together. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167815 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r--test/Transforms/InstCombine/cos-1.ll38
-rw-r--r--test/Transforms/InstCombine/cos-2.ll17
-rw-r--r--test/Transforms/InstCombine/double-float-shrink-1.ll (renamed from test/Transforms/SimplifyLibCalls/double-float-shrink.ll)262
-rw-r--r--test/Transforms/InstCombine/double-float-shrink-2.ll80
-rw-r--r--test/Transforms/InstCombine/exp2-1.ll76
-rw-r--r--test/Transforms/InstCombine/exp2-2.ll17
-rw-r--r--test/Transforms/InstCombine/pow-1.ll152
-rw-r--r--test/Transforms/InstCombine/pow-2.ll14
-rw-r--r--test/Transforms/SimplifyLibCalls/cos.ll14
-rw-r--r--test/Transforms/SimplifyLibCalls/exp2.ll38
-rw-r--r--test/Transforms/SimplifyLibCalls/floor.ll85
-rw-r--r--test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll33
-rw-r--r--test/Transforms/SimplifyLibCalls/pow2.ll37
13 files changed, 525 insertions, 338 deletions
diff --git a/test/Transforms/InstCombine/cos-1.ll b/test/Transforms/InstCombine/cos-1.ll
new file mode 100644
index 0000000000..b92e448abd
--- /dev/null
+++ b/test/Transforms/InstCombine/cos-1.ll
@@ -0,0 +1,38 @@
+; Test that the cos library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s -check-prefix=NO-FLOAT-SHRINK
+; RUN: opt < %s -instcombine -enable-double-float-shrink -S | FileCheck %s -check-prefix=DO-FLOAT-SHRINK
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+declare double @cos(double)
+
+; Check cos(-x) -> cos(x);
+
+define double @test_simplify1(double %d) {
+; NO-FLOAT-SHRINK: @test_simplify1
+ %neg = fsub double -0.000000e+00, %d
+ %cos = call double @cos(double %neg)
+; NO-FLOAT-SHRINK: call double @cos(double %d)
+ ret double %cos
+}
+
+define float @test_simplify2(float %f) {
+; DO-FLOAT-SHRINK: @test_simplify2
+ %conv1 = fpext float %f to double
+ %neg = fsub double -0.000000e+00, %conv1
+ %cos = call double @cos(double %neg)
+ %conv2 = fptrunc double %cos to float
+; DO-FLOAT-SHRINK: call float @cosf(float %f)
+ ret float %conv2
+}
+
+define float @test_simplify3(float %f) {
+; NO-FLOAT-SHRINK: @test_simplify3
+ %conv1 = fpext float %f to double
+ %neg = fsub double -0.000000e+00, %conv1
+ %cos = call double @cos(double %neg)
+; NO-FLOAT-SHRINK: call double @cos(double %conv1)
+ %conv2 = fptrunc double %cos to float
+ ret float %conv2
+}
diff --git a/test/Transforms/InstCombine/cos-2.ll b/test/Transforms/InstCombine/cos-2.ll
new file mode 100644
index 0000000000..2f2dfafe48
--- /dev/null
+++ b/test/Transforms/InstCombine/cos-2.ll
@@ -0,0 +1,17 @@
+; Test that the cos library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+declare float @cos(double)
+
+; Check that cos functions with the wrong prototype aren't simplified.
+
+define float @test_no_simplify1(double %d) {
+; CHECK: @test_no_simplify1
+ %neg = fsub double -0.000000e+00, %d
+ %cos = call float @cos(double %neg)
+; CHECK: call float @cos(double %neg)
+ ret float %cos
+}
diff --git a/test/Transforms/SimplifyLibCalls/double-float-shrink.ll b/test/Transforms/InstCombine/double-float-shrink-1.ll
index b4ab8b4ceb..e5448ee007 100644
--- a/test/Transforms/SimplifyLibCalls/double-float-shrink.ll
+++ b/test/Transforms/InstCombine/double-float-shrink-1.ll
@@ -1,98 +1,98 @@
-; RUN: opt < %s -simplify-libcalls -enable-double-float-shrink -S | FileCheck %s
+; RUN: opt < %s -instcombine -enable-double-float-shrink -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define float @acos_test(float %f) nounwind readnone {
; CHECK: acos_test
- %conv = fpext float %f to double
- %call = call double @acos(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @acos(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @acosf(float %f)
}
define double @acos_test2(float %f) nounwind readnone {
; CHECK: acos_test2
- %conv = fpext float %f to double
- %call = call double @acos(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @acos(double %conv)
+ ret double %call
; CHECK: call double @acos(double %conv)
}
define float @acosh_test(float %f) nounwind readnone {
; CHECK: acosh_test
- %conv = fpext float %f to double
- %call = call double @acosh(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @acosh(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @acoshf(float %f)
}
define double @acosh_test2(float %f) nounwind readnone {
; CHECK: acosh_test2
- %conv = fpext float %f to double
- %call = call double @acosh(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @acosh(double %conv)
+ ret double %call
; CHECK: call double @acosh(double %conv)
}
define float @asin_test(float %f) nounwind readnone {
; CHECK: asin_test
- %conv = fpext float %f to double
- %call = call double @asin(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @asin(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @asinf(float %f)
}
define double @asin_test2(float %f) nounwind readnone {
; CHECK: asin_test2
- %conv = fpext float %f to double
- %call = call double @asin(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @asin(double %conv)
+ ret double %call
; CHECK: call double @asin(double %conv)
}
define float @asinh_test(float %f) nounwind readnone {
; CHECK: asinh_test
- %conv = fpext float %f to double
- %call = call double @asinh(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @asinh(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @asinhf(float %f)
}
define double @asinh_test2(float %f) nounwind readnone {
; CHECK: asinh_test2
- %conv = fpext float %f to double
- %call = call double @asinh(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @asinh(double %conv)
+ ret double %call
; CHECK: call double @asinh(double %conv)
}
define float @atan_test(float %f) nounwind readnone {
; CHECK: atan_test
- %conv = fpext float %f to double
- %call = call double @atan(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @atan(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @atanf(float %f)
}
define double @atan_test2(float %f) nounwind readnone {
; CHECK: atan_test2
- %conv = fpext float %f to double
- %call = call double @atan(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @atan(double %conv)
+ ret double %call
; CHECK: call double @atan(double %conv)
}
define float @atanh_test(float %f) nounwind readnone {
; CHECK: atanh_test
- %conv = fpext float %f to double
- %call = call double @atanh(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @atanh(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @atanhf(float %f)
}
@@ -105,210 +105,210 @@ define double @atanh_test2(float %f) nounwind readnone {
}
define float @cbrt_test(float %f) nounwind readnone {
; CHECK: cbrt_test
- %conv = fpext float %f to double
- %call = call double @cbrt(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @cbrt(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @cbrtf(float %f)
}
define double @cbrt_test2(float %f) nounwind readnone {
; CHECK: cbrt_test2
- %conv = fpext float %f to double
- %call = call double @cbrt(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @cbrt(double %conv)
+ ret double %call
; CHECK: call double @cbrt(double %conv)
}
define float @exp_test(float %f) nounwind readnone {
; CHECK: exp_test
- %conv = fpext float %f to double
- %call = call double @exp(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @exp(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @expf(float %f)
}
define double @exp_test2(float %f) nounwind readnone {
; CHECK: exp_test2
- %conv = fpext float %f to double
- %call = call double @exp(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @exp(double %conv)
+ ret double %call
; CHECK: call double @exp(double %conv)
}
define float @expm1_test(float %f) nounwind readnone {
; CHECK: expm1_test
- %conv = fpext float %f to double
- %call = call double @expm1(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @expm1(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @expm1f(float %f)
}
define double @expm1_test2(float %f) nounwind readnone {
; CHECK: expm1_test2
- %conv = fpext float %f to double
- %call = call double @expm1(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @expm1(double %conv)
+ ret double %call
; CHECK: call double @expm1(double %conv)
}
define float @exp10_test(float %f) nounwind readnone {
; CHECK: exp10_test
- %conv = fpext float %f to double
- %call = call double @exp10(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @exp10(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @exp10f(float %f)
}
define double @exp10_test2(float %f) nounwind readnone {
; CHECK: exp10_test2
- %conv = fpext float %f to double
- %call = call double @exp10(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @exp10(double %conv)
+ ret double %call
; CHECK: call double @exp10(double %conv)
}
define float @log_test(float %f) nounwind readnone {
; CHECK: log_test
- %conv = fpext float %f to double
- %call = call double @log(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @log(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @logf(float %f)
}
define double @log_test2(float %f) nounwind readnone {
; CHECK: log_test2
- %conv = fpext float %f to double
- %call = call double @log(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @log(double %conv)
+ ret double %call
; CHECK: call double @log(double %conv)
}
define float @log10_test(float %f) nounwind readnone {
; CHECK: log10_test
- %conv = fpext float %f to double
- %call = call double @log10(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @log10(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @log10f(float %f)
}
define double @log10_test2(float %f) nounwind readnone {
; CHECK: log10_test2
- %conv = fpext float %f to double
- %call = call double @log10(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @log10(double %conv)
+ ret double %call
; CHECK: call double @log10(double %conv)
}
define float @log1p_test(float %f) nounwind readnone {
; CHECK: log1p_test
- %conv = fpext float %f to double
- %call = call double @log1p(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @log1p(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @log1pf(float %f)
}
define double @log1p_test2(float %f) nounwind readnone {
; CHECK: log1p_test2
- %conv = fpext float %f to double
- %call = call double @log1p(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @log1p(double %conv)
+ ret double %call
; CHECK: call double @log1p(double %conv)
}
define float @log2_test(float %f) nounwind readnone {
; CHECK: log2_test
- %conv = fpext float %f to double
- %call = call double @log2(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @log2(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @log2f(float %f)
}
define double @log2_test2(float %f) nounwind readnone {
; CHECK: log2_test2
- %conv = fpext float %f to double
- %call = call double @log2(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @log2(double %conv)
+ ret double %call
; CHECK: call double @log2(double %conv)
}
define float @logb_test(float %f) nounwind readnone {
; CHECK: logb_test
- %conv = fpext float %f to double
- %call = call double @logb(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @logb(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @logbf(float %f)
}
define double @logb_test2(float %f) nounwind readnone {
; CHECK: logb_test2
- %conv = fpext float %f to double
- %call = call double @logb(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @logb(double %conv)
+ ret double %call
; CHECK: call double @logb(double %conv)
}
define float @sin_test(float %f) nounwind readnone {
; CHECK: sin_test
- %conv = fpext float %f to double
- %call = call double @sin(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @sin(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @sinf(float %f)
}
define double @sin_test2(float %f) nounwind readnone {
; CHECK: sin_test2
- %conv = fpext float %f to double
- %call = call double @sin(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @sin(double %conv)
+ ret double %call
; CHECK: call double @sin(double %conv)
}
define float @sqrt_test(float %f) nounwind readnone {
; CHECK: sqrt_test
- %conv = fpext float %f to double
- %call = call double @sqrt(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @sqrt(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @sqrtf(float %f)
}
define double @sqrt_test2(float %f) nounwind readnone {
; CHECK: sqrt_test2
- %conv = fpext float %f to double
- %call = call double @sqrt(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @sqrt(double %conv)
+ ret double %call
; CHECK: call double @sqrt(double %conv)
}
define float @tan_test(float %f) nounwind readnone {
; CHECK: tan_test
- %conv = fpext float %f to double
- %call = call double @tan(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @tan(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @tanf(float %f)
}
define double @tan_test2(float %f) nounwind readnone {
; CHECK: tan_test2
- %conv = fpext float %f to double
- %call = call double @tan(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @tan(double %conv)
+ ret double %call
; CHECK: call double @tan(double %conv)
}
define float @tanh_test(float %f) nounwind readnone {
; CHECK: tanh_test
- %conv = fpext float %f to double
- %call = call double @tanh(double %conv)
- %conv1 = fptrunc double %call to float
- ret float %conv1
+ %conv = fpext float %f to double
+ %call = call double @tanh(double %conv)
+ %conv1 = fptrunc double %call to float
+ ret float %conv1
; CHECK: call float @tanhf(float %f)
}
define double @tanh_test2(float %f) nounwind readnone {
; CHECK: tanh_test2
- %conv = fpext float %f to double
- %call = call double @tanh(double %conv)
- ret double %call
+ %conv = fpext float %f to double
+ %call = call double @tanh(double %conv)
+ ret double %call
; CHECK: call double @tanh(double %conv)
}
diff --git a/test/Transforms/InstCombine/double-float-shrink-2.ll b/test/Transforms/InstCombine/double-float-shrink-2.ll
new file mode 100644
index 0000000000..7f6df92c96
--- /dev/null
+++ b/test/Transforms/InstCombine/double-float-shrink-2.ll
@@ -0,0 +1,80 @@
+; RUN: opt < %s -instcombine -S -mtriple "i386-pc-linux" | FileCheck -check-prefix=DO-SIMPLIFY %s
+; RUN: opt < %s -instcombine -S -mtriple "i386-pc-win32" | FileCheck -check-prefix=DONT-SIMPLIFY %s
+; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-win32" | FileCheck -check-prefix=C89-SIMPLIFY %s
+; RUN: opt < %s -instcombine -S -mtriple "i386-pc-mingw32" | FileCheck -check-prefix=DO-SIMPLIFY %s
+; RUN: opt < %s -instcombine -S -mtriple "x86_64-pc-mingw32" | FileCheck -check-prefix=DO-SIMPLIFY %s
+; RUN: opt < %s -instcombine -S -mtriple "sparc-sun-solaris" | FileCheck -check-prefix=DO-SIMPLIFY %s
+
+; DO-SIMPLIFY: call float @floorf(
+; DO-SIMPLIFY: call float @ceilf(
+; DO-SIMPLIFY: call float @roundf(
+; DO-SIMPLIFY: call float @nearbyintf(
+; DO-SIMPLIFY: call float @truncf(
+; DO-SIMPLIFY: call float @fabsf(
+
+; C89-SIMPLIFY: call float @floorf(
+; C89-SIMPLIFY: call float @ceilf(
+; C89-SIMPLIFY: call double @round(
+; C89-SIMPLIFY: call double @nearbyint(
+
+; DONT-SIMPLIFY: call double @floor(
+; DONT-SIMPLIFY: call double @ceil(
+; DONT-SIMPLIFY: call double @round(
+; DONT-SIMPLIFY: call double @nearbyint(
+; DONT-SIMPLIFY: call double @trunc(
+; DONT-SIMPLIFY: call double @fabs(
+
+declare double @floor(double)
+declare double @ceil(double)
+declare double @round(double)
+declare double @nearbyint(double)
+declare double @trunc(double)
+declare double @fabs(double)
+
+define float @test_floor(float %C) {
+ %D = fpext float %C to double
+ ; --> floorf
+ %E = call double @floor(double %D)
+ %F = fptrunc double %E to float
+ ret float %F
+}
+
+define float @test_ceil(float %C) {
+ %D = fpext float %C to double
+ ; --> ceilf
+ %E = call double @ceil(double %D)
+ %F = fptrunc double %E to float
+ ret float %F
+}
+
+define float @test_round(float %C) {
+ %D = fpext float %C to double
+ ; --> roundf
+ %E = call double @round(double %D)
+ %F = fptrunc double %E to float
+ ret float %F
+}
+
+define float @test_nearbyint(float %C) {
+ %D = fpext float %C to double
+ ; --> nearbyintf
+ %E = call double @nearbyint(double %D)
+ %F = fptrunc double %E to float
+ ret float %F
+}
+
+define float @test_trunc(float %C) {
+ %D = fpext float %C to double
+ ; --> truncf
+ %E = call double @trunc(double %D)
+ %F = fptrunc double %E to float
+ ret float %F
+}
+
+define float @test_fabs(float %C) {
+ %D = fpext float %C to double
+ ; --> fabsf
+ %E = call double @fabs(double %D)
+ %F = fptrunc double %E to float
+ ret float %F
+}
diff --git a/test/Transforms/InstCombine/exp2-1.ll b/test/Transforms/InstCombine/exp2-1.ll
new file mode 100644
index 0000000000..1b0ad50004
--- /dev/null
+++ b/test/Transforms/InstCombine/exp2-1.ll
@@ -0,0 +1,76 @@
+; Test that the exp2 library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+
+declare double @exp2(double)
+declare float @exp2f(float)
+
+; Check exp2(sitofp(x)) -> ldexp(1.0, sext(x)).
+
+define double @test_simplify1(i32 %x) {
+; CHECK: @test_simplify1
+ %conv = sitofp i32 %x to double
+ %ret = call double @exp2(double %conv)
+; CHECK: call double @ldexp
+ ret double %ret
+}
+
+define double @test_simplify2(i16 signext %x) {
+; CHECK: @test_simplify2
+ %conv = sitofp i16 %x to double
+ %ret = call double @exp2(double %conv)
+; CHECK: call double @ldexp
+ ret double %ret
+}
+
+define double @test_simplify3(i8 signext %x) {
+; CHECK: @test_simplify3
+ %conv = sitofp i8 %x to double
+ %ret = call double @exp2(double %conv)
+; CHECK: call double @ldexp
+ ret double %ret
+}
+
+define float @test_simplify4(i32 %x) {
+; CHECK: @test_simplify4
+ %conv = sitofp i32 %x to float
+ %ret = call float @exp2f(float %conv)
+; CHECK: call float @ldexpf
+ ret float %ret
+}
+
+; Check exp2(uitofp(x)) -> ldexp(1.0, zext(x)).
+
+define double @test_no_simplify1(i32 %x) {
+; CHECK: @test_no_simplify1
+ %conv = uitofp i32 %x to double
+ %ret = call double @exp2(double %conv)
+; CHECK: call double @exp2
+ ret double %ret
+}
+
+define double @test_simplify6(i16 zeroext %x) {
+; CHECK: @test_simplify6
+ %conv = uitofp i16 %x to double
+ %ret = call double @exp2(double %conv)
+; CHECK: call double @ldexp
+ ret double %ret
+}
+
+define double @test_simplify7(i8 zeroext %x) {
+; CHECK: @test_simplify7
+ %conv = uitofp i8 %x to double
+ %ret = call double @exp2(double %conv)
+; CHECK: call double @ldexp
+ ret double %ret
+}
+
+define float @test_simplify8(i8 zeroext %x) {
+; CHECK: @test_simplify8
+ %conv = uitofp i8 %x to float
+ %ret = call float @exp2f(float %conv)
+; CHECK: call float @ldexpf
+ ret float %ret
+}
diff --git a/test/Transforms/InstCombine/exp2-2.ll b/test/Transforms/InstCombine/exp2-2.ll
new file mode 100644
index 0000000000..bed063798e
--- /dev/null
+++ b/test/Transforms/InstCombine/exp2-2.ll
@@ -0,0 +1,17 @@
+; Test that the exp2 library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
+
+declare float @exp2(double)
+
+; Check that exp2 functions with the wrong prototype aren't simplified.
+
+define float @test_no_simplify1(i32 %x) {
+; CHECK: @test_no_simplify1
+ %conv = sitofp i32 %x to double
+ %ret = call float @exp2(double %conv)
+; CHECK: call float @exp2(double %conv)
+ ret float %ret
+}
diff --git a/test/Transforms/InstCombine/pow-1.ll b/test/Transforms/InstCombine/pow-1.ll
new file mode 100644
index 0000000000..c8e5f3806f
--- /dev/null
+++ b/test/Transforms/InstCombine/pow-1.ll
@@ -0,0 +1,152 @@
+; Test that the pow library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s
+; rdar://7251832
+
+; NOTE: The readonly attribute on the pow call should be preserved
+; in the cases below where pow is transformed into another function call.
+
+declare float @powf(float, float) nounwind readonly
+declare double @pow(double, double) nounwind readonly
+
+; Check pow(1.0, x) -> 1.0.
+
+define float @test_simplify1(float %x) {
+; CHECK: @test_simplify1
+ %retval = call float @powf(float 1.0, float %x)
+ ret float %retval
+; CHECK-NEXT: ret float 1.000000e+00
+}
+
+define double @test_simplify2(double %x) {
+; CHECK: @test_simplify2
+ %retval = call double @pow(double 1.0, double %x)
+ ret double %retval
+; CHECK-NEXT: ret double 1.000000e+00
+}
+
+; Check pow(2.0, x) -> exp2(x).
+
+define float @test_simplify3(float %x) {
+; CHECK: @test_simplify3
+ %retval = call float @powf(float 2.0, float %x)
+; CHECK-NEXT: [[EXP2F:%[a-z0-9]+]] = call float @exp2f(float %x) nounwind readonly
+ ret float %retval
+; CHECK-NEXT: ret float [[EXP2F]]
+}
+
+define double @test_simplify4(double %x) {
+; CHECK: @test_simplify4
+ %retval = call double @pow(double 2.0, double %x)
+; CHECK-NEXT: [[EXP2:%[a-z0-9]+]] = call double @exp2(double %x) nounwind readonly
+ ret double %retval
+; CHECK-NEXT: ret double [[EXP2]]
+}
+
+; Check pow(x, 0.0) -> 1.0.
+
+define float @test_simplify5(float %x) {
+; CHECK: @test_simplify5
+ %retval = call float @powf(float %x, float 0.0)
+ ret float %retval
+; CHECK-NEXT: ret float 1.000000e+00
+}
+
+define double @test_simplify6(double %x) {
+; CHECK: @test_simplify6
+ %retval = call double @pow(double %x, double 0.0)
+ ret double %retval
+; CHECK-NEXT: ret double 1.000000e+00
+}
+
+; Check pow(x, 0.5) -> fabs(sqrt(x)), where x != -infinity.
+
+define float @test_simplify7(float %x) {
+; CHECK: @test_simplify7
+ %retval = call float @powf(float %x, float 0.5)
+; CHECK-NEXT: [[SQRTF:%[a-z0-9]+]] = call float @sqrtf(float %x) nounwind readonly
+; CHECK-NEXT: [[FABSF:%[a-z0-9]+]] = call float @fabsf(float [[SQRTF]]) nounwind readonly
+; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq float %x, 0xFFF0000000000000
+; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], float 0x7FF0000000000000, float [[FABSF]]
+ ret float %retval
+; CHECK-NEXT: ret float [[SELECT]]
+}
+
+define double @test_simplify8(double %x) {
+; CHECK: @test_simplify8
+ %retval = call double @pow(double %x, double 0.5)
+; CHECK-NEXT: [[SQRT:%[a-z0-9]+]] = call double @sqrt(double %x) nounwind readonly
+; CHECK-NEXT: [[FABS:%[a-z0-9]+]] = call double @fabs(double [[SQRT]]) nounwind readonly
+; CHECK-NEXT: [[FCMP:%[a-z0-9]+]] = fcmp oeq double %x, 0xFFF0000000000000
+; CHECK-NEXT: [[SELECT:%[a-z0-9]+]] = select i1 [[FCMP]], double 0x7FF0000000000000, double [[FABS]]
+ ret double %retval
+; CHECK-NEXT: ret double [[SELECT]]
+}
+
+; Check pow(-infinity, 0.5) -> +infinity.
+
+define float @test_simplify9(float %x) {
+; CHECK: @test_simplify9
+ %retval = call float @powf(float 0xFFF0000000000000, float 0.5)
+ ret float %retval
+; CHECK-NEXT: ret float 0x7FF0000000000000
+}
+
+define double @test_simplify10(double %x) {
+; CHECK: @test_simplify10
+ %retval = call double @pow(double 0xFFF0000000000000, double 0.5)
+ ret double %retval
+; CHECK-NEXT: ret double 0x7FF0000000000000
+}
+
+; Check pow(x, 1.0) -> x.
+
+define float @test_simplify11(float %x) {
+; CHECK: @test_simplify11
+ %retval = call float @powf(float %x, float 1.0)
+ ret float %retval
+; CHECK-NEXT: ret float %x
+}
+
+define double @test_simplify12(double %x) {
+; CHECK: @test_simplify12
+ %retval = call double @pow(double %x, double 1.0)
+ ret double %retval
+; CHECK-NEXT: ret double %x
+}
+
+; Check pow(x, 2.0) -> x*x.
+
+define float @test_simplify13(float %x) {
+; CHECK: @test_simplify13
+ %retval = call float @powf(float %x, float 2.0)
+; CHECK-NEXT: [[SQUARE:%[a-z0-9]+]] = fmul float %x, %x
+ ret float %retval
+; CHECK-NEXT: ret float [[SQUARE]]
+}
+
+define double @test_simplify14(double %x) {
+; CHECK: @test_simplify14
+ %retval = call double @pow(double %x, double 2.0)
+; CHECK-NEXT: [[SQUARE:%[a-z0-9]+]] = fmul double %x, %x
+ ret double %retval
+; CHECK-NEXT: ret double [[SQUARE]]
+}
+
+; Check pow(x, -1.0) -> 1.0/x.
+
+define float @test_simplify15(float %x) {
+; CHECK: @test_simplify15
+ %retval = call float @powf(float %x, float -1.0)
+; CHECK-NEXT: [[RECIPROCAL:%[a-z0-9]+]] = fdiv float 1.000000e+00, %x
+ ret float %retval
+; CHECK-NEXT: ret float [[RECIPROCAL]]
+}
+
+define double @test_simplify16(double %x) {
+; CHECK: @test_simplify16
+ %retval = call double @pow(double %x, double -1.0)
+; CHECK-NEXT: [[RECIPROCAL:%[a-z0-9]+]] = fdiv double 1.000000e+00, %x
+ ret double %retval
+; CHECK-NEXT: ret double [[RECIPROCAL]]
+}
diff --git a/test/Transforms/InstCombine/pow-2.ll b/test/Transforms/InstCombine/pow-2.ll
new file mode 100644
index 0000000000..af64cda090
--- /dev/null
+++ b/test/Transforms/InstCombine/pow-2.ll
@@ -0,0 +1,14 @@
+; Test that the pow library call simplifier works correctly.
+;
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+declare float @pow(double, double)
+
+; Check that pow functions with the wrong prototype aren't simplified.
+
+define float @test_no_simplify1(double %x) {
+; CHECK: @test_no_simplify1
+ %retval = call float @pow(double 1.0, double %x)
+; CHECK-NEXT: call float @pow(double 1.000000e+00, double %x)
+ ret float %retval
+}
diff --git a/test/Transforms/SimplifyLibCalls/cos.ll b/test/Transforms/SimplifyLibCalls/cos.ll
deleted file mode 100644
index 6a8ce8c388..0000000000
--- a/test/Transforms/SimplifyLibCalls/cos.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
-
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
-target triple = "x86_64-unknown-linux-gnu"
-
-define double @foo(double %d) nounwind readnone {
-; CHECK: @foo
- %1 = fsub double -0.000000e+00, %d
- %2 = call double @cos(double %1) nounwind readnone
-; CHECK: call double @cos(double %d)
- ret double %2
-}
-
-declare double @cos(double) nounwind readnone
diff --git a/test/Transforms/SimplifyLibCalls/exp2.ll b/test/Transforms/SimplifyLibCalls/exp2.ll
deleted file mode 100644
index a5927757cf..0000000000
--- a/test/Transforms/SimplifyLibCalls/exp2.ll
+++ /dev/null
@@ -1,38 +0,0 @@
-; RUN: opt < %s -simplify-libcalls -S | grep "call.*ldexp" | count 4
-; rdar://5852514
-
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin8"
-
-define double @t1(i32 %x) nounwind {
-entry:
- %tmp12 = sitofp i32 %x to double ; <double> [#uses=1]
- %exp2 = tail call double @exp2( double %tmp12 ) ; <double> [#uses=1]
- ret double %exp2
-}
-
-define float @t4(i8 zeroext %x) nounwind {
-entry:
- %tmp12 = uitofp i8 %x to float ; <float> [#uses=1]
- %tmp3 = tail call float @exp2f( float %tmp12 ) nounwind readonly ; <float> [#uses=1]
- ret float %tmp3
-}
-
-declare float @exp2f(float) nounwind readonly
-
-define double @t3(i16 zeroext %x) nounwind {
-entry:
- %tmp12 = uitofp i16 %x to double ; <double> [#uses=1]
- %exp2 = tail call double @exp2( double %tmp12 ) ; <double> [#uses=1]
- ret double %exp2
-}
-
-define double @t2(i16 signext %x) nounwind {
-entry:
- %tmp12 = sitofp i16 %x to double ; <double> [#uses=1]
- %exp2 = tail call double @exp2( double %tmp12 ) ; <double> [#uses=1]
- ret double %exp2
-}
-
-declare double @exp2(double)
-
diff --git a/test/Transforms/SimplifyLibCalls/floor.ll b/test/Transforms/SimplifyLibCalls/floor.ll
deleted file mode 100644
index 93c62c2002..0000000000
--- a/test/Transforms/SimplifyLibCalls/floor.ll
+++ /dev/null
@@ -1,85 +0,0 @@
-; RUN: opt < %s -simplify-libcalls -S -mtriple "i386-pc-linux" | FileCheck -check-prefix=DO-SIMPLIFY %s
-; RUN: opt < %s -simplify-libcalls -S -mtriple "i386-pc-win32" | FileCheck -check-prefix=DONT-SIMPLIFY %s
-; RUN: opt < %s -simplify-libcalls -S -mtriple "x86_64-pc-win32" | FileCheck -check-prefix=C89-SIMPLIFY %s
-; RUN: opt < %s -simplify-libcalls -S -mtriple "i386-pc-mingw32" | FileCheck -check-prefix=DO-SIMPLIFY %s
-; RUN: opt < %s -simplify-libcalls -S -mtriple "x86_64-pc-mingw32" | FileCheck -check-prefix=DO-SIMPLIFY %s
-; RUN: opt < %s -simplify-libcalls -S -mtriple "sparc-sun-solaris" | FileCheck -check-prefix=DO-SIMPLIFY %s
-
-; DO-SIMPLIFY: call float @floorf(
-; DO-SIMPLIFY: call float @ceilf(
-; DO-SIMPLIFY: call float @roundf(
-; DO-SIMPLIFY: call float @nearbyintf(
-; DO-SIMPLIFY: call float @truncf(
-; DO-SIMPLIFY: call float @fabsf(
-
-; C89-SIMPLIFY: call float @floorf(
-; C89-SIMPLIFY: call float @ceilf(
-; C89-SIMPLIFY: call double @round(
-; C89-SIMPLIFY: call double @nearbyint(
-
-; DONT-SIMPLIFY: call double @floor(
-; DONT-SIMPLIFY: call double @ceil(
-; DONT-SIMPLIFY: call double @round(
-; DONT-SIMPLIFY: call double @nearbyint(
-; DONT-SIMPLIFY: call double @trunc(
-; DONT-SIMPLIFY: call double @fabs(
-
-declare double @floor(double)
-
-declare double @ceil(double)
-
-declare double @round(double)
-
-declare double @nearbyint(double)
-
-declare double @trunc(double)
-
-declare double @fabs(double)
-
-define float @test_floor(float %C) {
- %D = fpext float %C to double ; <double> [#uses=1]
- ; --> floorf
- %E = call double @floor( double %D ) ; <double> [#uses=1]
- %F = fptrunc double %E to float ; <float> [#uses=1]
- ret float %F
-}
-
-define float @test_ceil(float %C) {
- %D = fpext float %C to double ; <double> [#uses=1]
- ; --> ceilf
- %E = call double @ceil( double %D ) ; <double> [#uses=1]
- %F = fptrunc double %E to float ; <float> [#uses=1]
- ret float %F
-}
-
-define float @test_round(float %C) {
- %D = fpext float %C to double ; <double> [#uses=1]
- ; --> roundf
- %E = call double @round( double %D ) ; <double> [#uses=1]
- %F = fptrunc double %E to float ; <float> [#uses=1]
- ret float %F
-}
-
-define float @test_nearbyint(float %C) {
- %D = fpext float %C to double ; <double> [#uses=1]
- ; --> nearbyintf
- %E = call double @nearbyint( double %D ) ; <double> [#uses=1]
- %F = fptrunc double %E to float ; <float> [#uses=1]
- ret float %F
-}
-
-define float @test_trunc(float %C) {
- %D = fpext float %C to double
- ; --> truncf
- %E = call double @trunc(double %D)
- %F = fptrunc double %E to float
- ret float %F
-}
-
-define float @test_fabs(float %C) {
- %D = fpext float %C to double
- ; --> fabsf
- %E = call double @fabs(double %D)
- %F = fptrunc double %E to float
- ret float %F
-}
diff --git a/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll b/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll
deleted file mode 100644
index 0480fdda89..0000000000
--- a/test/Transforms/SimplifyLibCalls/pow-to-sqrt.ll
+++ /dev/null
@@ -1,33 +0,0 @@
-; RUN: opt < %s -simplify-libcalls -S | FileCheck %s
-; rdar://7251832
-
-; SimplifyLibcalls should optimize pow(x, 0.5) to sqrt plus code to handle
-; special cases. The readonly attribute on the call should be preserved.
-
-; CHECK: define float @foo(float %x) nounwind {
-; CHECK: %sqrtf = call float @sqrtf(float %x) nounwind readonly
-; CHECK: %fabsf = call float @fabsf(float %sqrtf) nounwind readonly
-; CHECK: %1 = fcmp oeq float %x, 0xFFF0000000000000
-; CHECK: %retval = select i1 %1, float 0x7FF0000000000000, float %fabsf
-; CHECK: ret float %retval
-
-define float @foo(float %x) nounwind {
- %retval = call float @powf(float %x, float 0.5)
- ret float %retval
-}
-
-; CHECK: define double @doo(double %x) nounwind {
-; CHECK: %sqrt = call double @sqrt(double %x) nounwind readonly
-; CHECK: %fabs = call double @fabs(double %sqrt) nounwind readonly
-; CHECK: %1 = fcmp oeq double %x, 0xFFF0000000000000
-; CHECK: %retval = select i1 %1, double 0x7FF0000000000000, double %fabs
-; CHECK: ret double %retval
-; CHECK: }
-
-define double @doo(double %x) nounwind {
- %retval = call double @pow(double %x, double 0.5)
- ret double %retval
-}
-
-declare float @powf(float, float) nounwind readonly
-declare double @pow(double, double) nounwind readonly
diff --git a/test/Transforms/SimplifyLibCalls/pow2.ll b/test/Transforms/SimplifyLibCalls/pow2.ll
deleted file mode 100644
index f0964e7d6d..0000000000
--- a/test/Transforms/SimplifyLibCalls/pow2.ll
+++ /dev/null
@@ -1,37 +0,0 @@
-; Testcase for calls to the standard C "pow" function
-;
-; RUN: opt < %s -simplify-libcalls -S | not grep "call .pow"
-
-
-declare double @pow(double, double)
-declare float @powf(float, float)
-
-define double @test1(double %X) {
- %Y = call double @pow( double %X, double 0.000000e+00 ) ; <double> [#uses=1]
- ret double %Y
-}
-
-define double @test2(double %X) {
- %Y = call double @pow( double %X, double -0.000000e+00 ) ; <double> [#uses=1]
- ret double %Y
-}
-
-define double @test3(double %X) {
- %Y = call double @pow( double 1.000000e+00, double %X ) ; <double> [#uses=1]
- ret double %Y
-}
-
-define double @test4(double %X) {
- %Y = call double @pow( double %X, double 2.0)
- ret double %Y
-}
-
-define float @test4f(float %X) {
- %Y = call float @powf( float %X, float 2.0)
- ret float %Y
-}
-
-define float @test5f(float %X) {
- %Y = call float @powf(float 2.0, float %X) ;; exp2
- ret float %Y
-}