Skip to content
  • Jeremy Evans's avatar
    fe6245b4
    Fix rb_fix_mul_fix on OpenBSD/mips64 · fe6245b4
    Jeremy Evans authored
    This fixes invalid and inconsistent results for the Fixnum*Fixnum case
    where the result of the multiplication does not fit in 64-bit
    on OpenBSD/mips64.  For example:
    
      $  for x in 1 23; do ruby31 -e 'p(54306000000000*86400)'; done
      14409380628474329524
      11410664325873689790
    
    Cases where an argument was Bignum, as well as cases where the result
    of the multiplication fits in 64-bit are fine:
    
      $ for x in 1 23; do ruby31 -e 'p(54306000*86400)'; done
      4692038400000
      4692038400000
    
      $ for x in 1 23; do ruby31 -e 'p(5430600000000000000000*86400)'; done
      469203840000000000000000000
      469203840000000000000000000
    
    This was originally discovered by running the tests for the openssl gem
    on OpenBSD/mips64 and having one test fail for a date far in the future.
    I eventually traced this to the generic multiplication issue.
    
    The underlying cause is using the int128_t type. This avoids use of the
    int128_t type in this case, falling back to the slower conversion code,
    which in the overflow case, turns the Fixnums into Bignums, then
    performs the multiplication.
    fe6245b4
    Fix rb_fix_mul_fix on OpenBSD/mips64
    Jeremy Evans authored
    This fixes invalid and inconsistent results for the Fixnum*Fixnum case
    where the result of the multiplication does not fit in 64-bit
    on OpenBSD/mips64.  For example:
    
      $  for x in 1 23; do ruby31 -e 'p(54306000000000*86400)'; done
      14409380628474329524
      11410664325873689790
    
    Cases where an argument was Bignum, as well as cases where the result
    of the multiplication fits in 64-bit are fine:
    
      $ for x in 1 23; do ruby31 -e 'p(54306000*86400)'; done
      4692038400000
      4692038400000
    
      $ for x in 1 23; do ruby31 -e 'p(5430600000000000000000*86400)'; done
      469203840000000000000000000
      469203840000000000000000000
    
    This was originally discovered by running the tests for the openssl gem
    on OpenBSD/mips64 and having one test fail for a date far in the future.
    I eventually traced this to the generic multiplication issue.
    
    The underlying cause is using the int128_t type. This avoids use of the
    int128_t type in this case, falling back to the slower conversion code,
    which in the overflow case, turns the Fixnums into Bignums, then
    performs the multiplication.
Loading