Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
libgst: Add alternative multiplication overflow check
Apple clang on OSX and the version on FreeBSD optimize the
multiplication check away. Clang introduced a family of
builtins to do the multiplication and check for the overflow
and GCC made the API usable. For clang we would need to know
if intptr_t is of type int, long int, long long int and
then use the smul, smull smulll.
Luckily clang is adopting the better interface and this is
what we are starting to use now. This means the new code
will be used on GCC5 (and later) and some future versions of
clang.

2015-11-07  Holger Hans Peter Freyther  <holger@freyther.de>

	* build-aux/overflow-builtins.m4: Add new macro.
	* configure.ac: Use GST_C_OVERFLOW_BUILTINS macro.

2015-11-07  Holger Hans Peter Freyther  <holger@freyther.de>

	* interp.inl: Add alternative mul_with_check implementation.
  • Loading branch information
zecke committed Nov 7, 2015
1 parent 504a8b8 commit 72ada18
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 0 deletions.
5 changes: 5 additions & 0 deletions ChangeLog
@@ -1,3 +1,8 @@
2015-11-07 Holger Hans Peter Freyther <holger@freyther.de>

* build-aux/overflow-builtins.m4: Add new macro.
* configure.ac: Use GST_C_OVERFLOW_BUILTINS macro.

2015-11-07 Holger Hans Peter Freyther <holger@freyther.de>

* configure.ac: Increase the version number after the
Expand Down
23 changes: 23 additions & 0 deletions build-aux/overflow-builtins.m4
@@ -0,0 +1,23 @@
dnl Check whether the host supports synchronization builtins.

AC_DEFUN([GST_C_OVERFLOW_BUILTINS], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_CACHE_CHECK([whether the host supports __builtin_mul_overflow],
gst_cv_have_builtin_mul_overflow, [
save_CFLAGS="$CFLAGS"
case $host in
i?86-apple-darwin*) ;;
i?86-*-*) CFLAGS="$CFLAGS -march=i486" ;;
esac
AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foovar = 0;]], [[
if (__builtin_mul_overflow(44444, 55555, &foovar))
return 23;]])],
[gst_cv_have_builtin_mul_overflow=yes],
[gst_cv_have_builtin_mul_overflow=no])
CFLAGS="$save_CFLAGS"
])
if test $gst_cv_have_builtin_mul_overflow = yes; then
AC_DEFINE(HAVE_OVERFLOW_BUILTINS, 1,
[Define to 1 if the host supports __builtin_*_overflow builtins])
fi
])
1 change: 1 addition & 0 deletions configure.ac
Expand Up @@ -243,6 +243,7 @@ GST_C_SYNC_BUILTINS
if test $gst_cv_have_sync_fetch_and_add = no; then
AC_MSG_ERROR([Synchronization primitives not found, please use a newer compiler.])
fi
GST_C_OVERFLOW_BUILTINS

GST_LOCK
AC_SYS_LARGEFILE
Expand Down
4 changes: 4 additions & 0 deletions libgst/ChangeLog
@@ -1,3 +1,7 @@
2015-11-07 Holger Hans Peter Freyther <holger@freyther.de>

* interp.inl: Add alternative mul_with_check implementation.

2015-08-02 Holger Hans Peter Freyther <holger@freyther.de>

* events.c: Use else instead of else if in
Expand Down
22 changes: 22 additions & 0 deletions libgst/interp.inl
Expand Up @@ -159,6 +159,27 @@ sub_with_check (OOP op1, OOP op2, mst_Boolean *overflow)
OOP
mul_with_check (OOP op1, OOP op2, mst_Boolean *overflow)
{
#ifdef HAVE_OVERFLOW_BUILTINS
intptr_t a = TO_INT (op1);
intptr_t b = TO_INT (op2);
intptr_t result;

if (__builtin_mul_overflow(a, b, &result))
{
*overflow = true;
return FROM_INT(0);
}


if (result < MIN_ST_INT || result > MAX_ST_INT)
{
*overflow = true;
return FROM_INT(0);
}

*overflow = false;
return FROM_INT(result);
#else
intptr_t a = TO_INT (op1);
intptr_t b = TO_INT (op2);
intmax_t result = (intmax_t)a * b;
Expand Down Expand Up @@ -188,6 +209,7 @@ mul_with_check (OOP op1, OOP op2, mst_Boolean *overflow)
}

return FROM_INT (0);
#endif
}

/* State of the random generator.
Expand Down

0 comments on commit 72ada18

Please sign in to comment.