aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-03-10 11:43:30 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-03-10 11:43:30 -0700
commit34e9973bcb1c917acdc3b61e72bc583556d115ea (patch)
tree2babd94bfd584441473b967c7fcff3a690671c96
parentb04c754c0294d84e85d3546b7c2ef5e0de86c726 (diff)
update float ffi rules
-rw-r--r--lib/Target/JSBackend/CallHandlers.h10
-rw-r--r--test/CodeGen/JS/ffis-f32.ll78
-rw-r--r--test/CodeGen/JS/ffis.ll78
3 files changed, 164 insertions, 2 deletions
diff --git a/lib/Target/JSBackend/CallHandlers.h b/lib/Target/JSBackend/CallHandlers.h
index e1e8cbb46f..8ae8c26c1d 100644
--- a/lib/Target/JSBackend/CallHandlers.h
+++ b/lib/Target/JSBackend/CallHandlers.h
@@ -101,8 +101,14 @@ DEF_CALL_HANDLER(__default__, {
}
if (NumArgs > 0) text += ",";
}
- // this is an ffi call if we need casts, and it is not a Math_ builtin (with just 1 arg - Math with more args is different XXX)
- bool FFI = NeedCasts && (NumArgs > 1 || Name.find("Math_") != 0);
+ // this is an ffi call if we need casts, and it is not a special Math_ builtin
+ bool FFI = NeedCasts;
+ if (FFI && Name.find("Math_") == 0) {
+ if (Name == "Math_ceil" || Name == "Math_floor" || Name == "Math_min" || Name == "Math_max" || Name == "Math_sqrt" || Name == "Math_abs") {
+ // This special Math builtin is optimizable with all types, including floats, so can treat it as non-ffi
+ FFI = false;
+ }
+ }
unsigned FFI_OUT = FFI ? ASM_FFI_OUT : 0;
for (int i = 0; i < NumArgs; i++) {
if (!NeedCasts) {
diff --git a/test/CodeGen/JS/ffis-f32.ll b/test/CodeGen/JS/ffis-f32.ll
new file mode 100644
index 0000000000..39d3c65b6c
--- /dev/null
+++ b/test/CodeGen/JS/ffis-f32.ll
@@ -0,0 +1,78 @@
+; RUN: llc -emscripten-precise-f32 -march=js < %s | FileCheck %s
+
+; Use proper types to ffi calls, with float32
+
+; CHECK: (+Math_sqrt(+1));
+; CHECK-NEXT: (Math_fround(Math_sqrt(Math_fround(+1))));
+; CHECK-NEXT: (+Math_sqrt((+$d)));
+; CHECK-NEXT: (Math_fround(Math_sqrt((Math_fround($f)))));
+; CHECK-NEXT: (+Math_ceil(+1));
+; CHECK-NEXT: (Math_fround(Math_ceil(Math_fround(+1))));
+; CHECK-NEXT: (+Math_floor(+1));
+; CHECK-NEXT: (Math_fround(Math_floor(Math_fround(+1))));
+; CHECK-NEXT: (+_min(+1,+1));
+; CHECK-NEXT: (Math_fround(+(_fmin(+1,+1))));
+; CHECK-NEXT: (+_max(+1,+1));
+; CHECK-NEXT: (Math_fround(+(_fmax(+1,+1))));
+; CHECK-NEXT: (+Math_abs(+1));
+; CHECK-NEXT: (Math_fround(+(_absf(+1))));
+; CHECK-NEXT: (+Math_sin(+1));
+; CHECK-NEXT: (Math_fround(+(Math_sin(+1))));
+define void @foo(i32 %x) {
+entry:
+ %f = fadd float 1.0, 2.0
+ %d = fadd double 1.0, 2.0
+
+ %sqrtd = call double @sqrt(double 1.0)
+ %sqrtf = call float @sqrtf(float 1.0)
+ %sqrtdv = call double @sqrt(double %d) ; check vars too
+ %sqrtfv = call float @sqrtf(float %f)
+
+ %ceild = call double @ceil(double 1.0)
+ %ceilf = call float @ceilf(float 1.0)
+
+ %floord = call double @floor(double 1.0)
+ %floorf = call float @floorf(float 1.0)
+
+ ; these could be optimized in theory
+
+ %mind = call double @min(double 1.0, double 1.0)
+ %minf = call float @fmin(float 1.0, float 1.0)
+
+ %maxd = call double @max(double 1.0, double 1.0)
+ %maxf = call float @fmax(float 1.0, float 1.0)
+
+ %absd = call double @abs(double 1.0)
+ %absf = call float @absf(float 1.0)
+
+ ; sin is NOT optimizable with floats
+
+ %sind = call double @sin(double 1.0)
+ %sinf = call float @sinf(float 1.0)
+
+ ret void
+}
+
+declare double @sqrt(double %x)
+declare float @sqrtf(float %x)
+
+declare double @ceil(double %x)
+declare float @ceilf(float %x)
+
+declare double @floor(double %x)
+declare float @floorf(float %x)
+
+declare double @min(double %x, double %y)
+declare float @fmin(float %x, float %y)
+
+declare double @max(double %x, double %y)
+declare float @fmax(float %x, float %y)
+
+declare double @abs(double %x)
+declare float @absf(float %x)
+
+declare double @sin(double %x)
+declare float @sinf(float %x)
+
+attributes #0 = { nounwind readnone }
+
diff --git a/test/CodeGen/JS/ffis.ll b/test/CodeGen/JS/ffis.ll
new file mode 100644
index 0000000000..9e3de7bad1
--- /dev/null
+++ b/test/CodeGen/JS/ffis.ll
@@ -0,0 +1,78 @@
+; RUN: llc -march=js < %s | FileCheck %s
+
+; Use proper types to ffi calls, no float32
+
+; CHECK: (+Math_sqrt(+1));
+; CHECK-NEXT: (+Math_sqrt(+1));
+; CHECK-NEXT: (+Math_sqrt((+$d)));
+; CHECK-NEXT: (+Math_sqrt((+$f)));
+; CHECK-NEXT: (+Math_ceil(+1));
+; CHECK-NEXT: (+Math_ceil(+1));
+; CHECK-NEXT: (+Math_floor(+1));
+; CHECK-NEXT: (+Math_floor(+1));
+; CHECK-NEXT: (+_min(+1,+1));
+; CHECK-NEXT: (+_fmin(+1,+1));
+; CHECK-NEXT: (+_max(+1,+1));
+; CHECK-NEXT: (+_fmax(+1,+1));
+; CHECK-NEXT: (+Math_abs(+1));
+; CHECK-NEXT: (+_absf(+1));
+; CHECK-NEXT: (+Math_sin(+1));
+; CHECK-NEXT: (+Math_sin(+1));
+define void @foo(i32 %x) {
+entry:
+ %f = fadd float 1.0, 2.0
+ %d = fadd double 1.0, 2.0
+
+ %sqrtd = call double @sqrt(double 1.0)
+ %sqrtf = call float @sqrtf(float 1.0)
+ %sqrtdv = call double @sqrt(double %d) ; check vars too
+ %sqrtfv = call float @sqrtf(float %f)
+
+ %ceild = call double @ceil(double 1.0)
+ %ceilf = call float @ceilf(float 1.0)
+
+ %floord = call double @floor(double 1.0)
+ %floorf = call float @floorf(float 1.0)
+
+ ; these could be optimized in theory
+
+ %mind = call double @min(double 1.0, double 1.0)
+ %minf = call float @fmin(float 1.0, float 1.0)
+
+ %maxd = call double @max(double 1.0, double 1.0)
+ %maxf = call float @fmax(float 1.0, float 1.0)
+
+ %absd = call double @abs(double 1.0)
+ %absf = call float @absf(float 1.0)
+
+ ; sin is NOT optimizable with floats
+
+ %sind = call double @sin(double 1.0)
+ %sinf = call float @sinf(float 1.0)
+
+ ret void
+}
+
+declare double @sqrt(double %x)
+declare float @sqrtf(float %x)
+
+declare double @ceil(double %x)
+declare float @ceilf(float %x)
+
+declare double @floor(double %x)
+declare float @floorf(float %x)
+
+declare double @min(double %x, double %y)
+declare float @fmin(float %x, float %y)
+
+declare double @max(double %x, double %y)
+declare float @fmax(float %x, float %y)
+
+declare double @abs(double %x)
+declare float @absf(float %x)
+
+declare double @sin(double %x)
+declare float @sinf(float %x)
+
+attributes #0 = { nounwind readnone }
+