[PATCH v2.0] Use saturated arithmetic for overflow detection.

Paul Eggert eggert@cs.ucla.edu
Sun Nov 3 08:20:00 GMT 2013


Ondřej Bílka wrote:
> checking takes 10 bytes for branch version, 12 bytes in branchfree
> version.

When I try it, the branch version takes one byte more than
the branchfree version.  This is when I do branching (or branchfree)
for both adding and multiplying.  Here's the testcase.  Compiled
with -O3, foo_branch is 32 bytes and foo_branchfree 31.

#include <stdint.h>
#include <stdlib.h>

static inline size_t
add_sat_branch (size_t x, size_t y)
{
  size_t ret;
  asm ("add %%rdx, %%rax; jno 1f; xor %%rax, %%rax; not %%rax; 1:" : "=a" (ret) : "a" (x) , "d" (y));
  return ret;
}

static inline size_t
add_sat_branchfree (size_t x, size_t y)
{
  size_t ret, scratch;
  asm ("add %%rdx, %%rax; sbb %%rdx, %%rdx; or %%rdx, %%rax" : "=a" (ret), "=d" (scratch) : "a" (x) , "d" (y));
  return ret;
}

static inline size_t
mul_sat_branch (size_t x, size_t y)
{
  size_t ret;
  asm ("mul %%rdx; jno 1f; xor %%rax, %%rax; not %%rax; 1:" : "=a" (ret) : "a" (x) , "d" (y));
  return ret;
}

static inline size_t
mul_sat_branchfree (size_t x, size_t y)
{
  size_t ret;
  size_t scratch;
  asm ("mul %%rdx; sbb %%rdx, %%rdx; or %%rdx, %%rax" : "=a" (ret), "=d" (scratch) : "a" (x) , "d" (y));
  return ret;
}

size_t
foo_branch (size_t a)
{
  return add_sat_branch (mul_sat_branch (a, 42 * 3), 8);
}

size_t
foo_branchfree (size_t a)
{
  return add_sat_branchfree (mul_sat_branchfree (a, 42 * 3), 8);
}



More information about the Libc-alpha mailing list