106 Commits

Author SHA1 Message Date
Veikka Tuominen
62ff8871ed stage2+stage1: remove type parameter from bit builtins
Closes #12529
Closes #12511
Closes #6835
2022-08-22 11:19:20 +03:00
Hiroaki Nakamura
3e667fd292 Use Managed.len in sub, divFloor, and divTrunc too 2022-07-16 11:46:13 +09:00
Hiroaki Nakamura
0cee8372cf Use Managed.len() instead of Managed.toConst().limbs.len 2022-07-16 08:14:16 +09:00
Hiroaki Nakamura
d63604b116 Fix std.math.big.int.Managed capacity after mul and sqr 2022-07-16 00:08:55 +09:00
Andrew Kelley
54454fd010 std.math.big.int: breaking API changes to prevent UAF
Many of the Managed methods accepted by-val parameters which could
reference Limb slices that became invalid memory after any
ensureCapacity calls. Now, Managed methods accept `*const Managed`
parameters so that if the function allows aliasing and the
ensure-capacity call resizes the Limb slice, it also affects the
aliased parameters, avoiding use-after-free bugs.

This is a breaking change that reduces the requirement for callsites to
manually make the ensure-capacity changes prior to calling many of the
Managed methods.

Closes #11897
2022-06-29 22:06:27 -04:00
Mikael Berthe
47c4d44502
std.math.big.int: update Managed.toString() to use provided allocator (#11839) 2022-06-13 17:19:37 +02:00
Veikka Tuominen
9431100736 Sema: apply previous changes to validateUnionInit 2022-06-01 13:01:39 +03:00
Ali Chraghi
0e6285c8fc math: make cast return optional instead of an error 2022-05-27 16:43:33 -04:00
Veikka Tuominen
845a30624f std: add workaround for stage2 bug 2022-04-15 11:17:19 +03:00
Damien Firmenich
5fafcc2b62
zig fmt: remove trailing whitespace on doc comments
Fixes #11353

The renderer treats comments and doc comments differently since doc
comments are parsed into the Ast. This commit adds a check after getting
the text for the doc comment and trims whitespace at the end before
rendering.

The `a = 0,` in the test is here to avoid a ParseError while parsing the
test.
2022-04-05 18:08:33 +03:00
Marc Tiehuis
2e0de0b4e2
math/big: correct fix for divmod (#11271)
Fixes #11166.
2022-03-23 19:24:25 +01:00
Marc Tiehuis
8bab1b405f math: fix big.int div, gcd and bitAnd edge-cases
Fixes #10932.
2022-03-10 13:56:07 -05:00
Cody Tapscott
ef417f19e1 stage2: Implement @bitReverse and @byteSwap
This change implements the above built-ins for Sema and the LLVM
backend. Other backends have had placeholders added for lowering.
2022-02-18 14:28:32 -07:00
Cody Tapscott
7b72fc6bbc Add abi_size parameter to read/writeTwosComplement
Big-int functions were updated to respect the provided abi_size, rather
than inferring a potentially incorrect abi_size implicitly.

In combination with the convention that any required padding bits are
added on the MSB end, this means that exotic integers can potentially
have a well-defined memory layout.
2022-02-13 13:26:59 -07:00
Cody Tapscott
70d7f87be0 Fix up sign handling and add arbitrary-length integer support to @bitCast() 2022-02-11 08:49:19 -07:00
Marc Tiehuis
53e6c719ef std/math: optimize division with divisors less than a half-limb
This adds a new path which avoids using compiler_rt generated div
udivmod instructions in the case that a divisor is less than half the
max usize value. Two half-limb divisions are performed instead which
ensures that non-emulated division instructions are actually used. This
does not improve the udivmod code which should still be reviewed
independently of this issue.

Notably this improves the performance of the toString implementation of
non-power-of-two bases considerably.

Division performance is improved ~1000% based on some coarse testing.

The following test code is used to provide a rough comparison between
the old vs. new method.

```
const std = @import("std");
const Managed = std.math.big.int.Managed;

const allocator = std.heap.c_allocator;

fn fib(a: *Managed, n: usize) !void {
    var b = try Managed.initSet(allocator, 1);
    defer b.deinit();
    var c = try Managed.init(allocator);
    defer c.deinit();

    var i: usize = 0;
    while (i < n) : (i += 1) {
        try c.add(a.toConst(), b.toConst());

        a.swap(&b);
        b.swap(&c);
    }
}

pub fn main() !void {
    var a = try Managed.initSet(allocator, 0);
    defer a.deinit();

    try fib(&a, 1_000_000);

    // Note: Next two lines (and printed digit count) omitted on no-print version.
    const as = try a.toString(allocator, 10, .lower);
    defer allocator.free(as);

    std.debug.print("fib: digit count: {}, limb count: {}\n", .{ as.len, a.limbs.len });
}
```

```
==> time.no-print <==
limb count: 10849

________________________________________________________
Executed in   10.60 secs    fish           external
   usr time   10.44 secs    0.00 millis   10.44 secs
   sys time    0.02 secs    1.12 millis    0.02 secs

==> time.old <==
fib: digit count: 208988, limb count: 10849

________________________________________________________
Executed in   22.78 secs    fish           external
   usr time   22.43 secs    1.01 millis   22.43 secs
   sys time    0.03 secs    0.13 millis    0.03 secs

==> time.optimized <==
fib: digit count: 208988, limb count: 10849

________________________________________________________
Executed in   11.59 secs    fish           external
   usr time   11.56 secs    1.03 millis   11.56 secs
   sys time    0.03 secs    0.12 millis    0.03 secs
```

Perf data for non-optimized and optimized, verifying no udivmod is
generated by the new code.

```
$ perf report -i perf.data.old --stdio
- Total Lost Samples: 0
-
- Samples: 90K of event 'cycles:u'
- Event count (approx.): 71603695208
-
- Overhead  Command  Shared Object     Symbol
- ........  .......  ................  ...........................................
-
    52.97%  t        t                 [.] compiler_rt.udivmod.udivmod
    45.97%  t        t                 [.] std.math.big.int.Mutable.addCarry
     0.83%  t        t                 [.] main
     0.08%  t        libc-2.33.so      [.] __memmove_avx_unaligned_erms
     0.08%  t        t                 [.] __udivti3
     0.03%  t        [unknown]         [k] 0xffffffff9a0010a7
     0.02%  t        t                 [.] std.math.big.int.Managed.ensureCapacity
     0.01%  t        libc-2.33.so      [.] _int_malloc
     0.00%  t        libc-2.33.so      [.] __malloc_usable_size
     0.00%  t        libc-2.33.so      [.] _int_free
     0.00%  t        t                 [.] 0x0000000000004a80
     0.00%  t        t                 [.] std.heap.CAllocator.resize
     0.00%  t        libc-2.33.so      [.] _mid_memalign
     0.00%  t        libc-2.33.so      [.] sysmalloc
     0.00%  t        libc-2.33.so      [.] __posix_memalign
     0.00%  t        t                 [.] std.heap.CAllocator.alloc
     0.00%  t        ld-2.33.so        [.] do_lookup_x

$ perf report -i perf.data.optimized --stdio
- Total Lost Samples: 0
-
- Samples: 46K of event 'cycles:u'
- Event count (approx.): 36790112336
-
- Overhead  Command  Shared Object     Symbol
- ........  .......  ................  ...........................................
-
    79.98%  t        t                 [.] std.math.big.int.Mutable.addCarry
    15.14%  t        t                 [.] main
     4.58%  t        t                 [.] std.math.big.int.Managed.ensureCapacity
     0.21%  t        libc-2.33.so      [.] __memmove_avx_unaligned_erms
     0.05%  t        [unknown]         [k] 0xffffffff9a0010a7
     0.02%  t        libc-2.33.so      [.] _int_malloc
     0.01%  t        t                 [.] std.heap.CAllocator.alloc
     0.01%  t        libc-2.33.so      [.] __malloc_usable_size
     0.00%  t        libc-2.33.so      [.] systrim.constprop.0
     0.00%  t        libc-2.33.so      [.] _mid_memalign
     0.00%  t        t                 [.] 0x0000000000000c7d
     0.00%  t        libc-2.33.so      [.] malloc
     0.00%  t        ld-2.33.so        [.] check_match
```

Closes #10630.
2022-02-06 21:39:34 -05:00
Robin Voetter
f3d635b668 stage2: @addWithOverflow 2021-12-21 01:41:51 +01:00
Lee Cannon
85de022c56
allocgate: std Allocator interface refactor 2021-11-30 23:32:47 +00:00
Andrew Kelley
902df103c6 std lib API deprecations for the upcoming 0.9.0 release
See #3811
2021-11-30 00:13:07 -07:00
Andrew Kelley
d6067db062 stage2: implement @popCount for non-vectors 2021-10-29 17:49:02 -07:00
Robin Voetter
df167af0b6
Revert 83bdbb2 and a587dd0 (#10028) 2021-10-25 14:00:10 +02:00
Robin Voetter
c563521d44 big ints: tighten some more division memory requirements 2021-10-24 02:56:48 +02:00
Robin Voetter
83bdbb2abb big ints: Make calcLimbLen always work at comptime, even if parameter is runtime 2021-10-24 02:56:48 +02:00
Robin Voetter
c905ceb23c big ints: fix divFloor 2021-10-24 02:56:48 +02:00
Robin Voetter
87b7b31557 big ints: improve division 2021-10-24 01:21:33 +02:00
Andrew Kelley
7f70c27e9d stage2: more division support
AIR:
 * div is renamed to div_trunc.
 * Add div_float, div_floor, div_exact.
   - Implemented in Sema and LLVM codegen. C backend has a stub.

Improvements to std.math.big.Int:
 * Add `eqZero` function to `Mutable`.
 * Fix incorrect results for `divFloor`.

Compiler-rt:
 * Add muloti4 to the stage2 section.
2021-10-21 19:05:26 -07:00
Robin Voetter
a3c9bfef30 stage2: truncation
* Also fixes a related case where big int truncate would assume that the
input fits in the output limbs buffer
2021-10-21 20:10:27 -04:00
Robin Voetter
6a3659c4e0 big.int: 2s-complement binary wrapping not 2021-10-17 20:33:04 +02:00
Robin Voetter
1e09157b53 big ints: Fix set(signed int minimum) panic 2021-10-16 11:32:05 +02:00
Robin Voetter
efa4f76c8b big ints: Saturating left shift + tests 2021-10-16 11:32:05 +02:00
Andrew Kelley
78902db68b stage2: fix comptime @bitCast
Before, Sema for comptime `@bitCast` would return the same Value but
change the Type. This gave invalid results because, for example, an
integer Value when the Type is a float would be interpreted numerically,
but `@bitCast` needs it to reinterpret how they would be stored in
memory.

This requires a mechanism to serialize a Value to a byte buffer and
deserialize a Value from a byte buffer.

Not done yet, but needs to happen: comptime dereferencing a pointer
to a Decl needs to perform a comptime bitcast on the loaded value.
Currently the value is silently wrong in the same way that `@bitCast`
was silently wrong before this commit.

The logic in Value for handling readFromMemory for large integers is
only correct for small integers. It needs to be fleshed out for proper
big integers.

As part of this change:
 * std.math.big.Int: initial implementations of readTwosComplement and
   writeTwosComplement. They only support bit_count <= 128 so far and
   panic otherwise.
 * compiler-rt: move the compareXf2 exports over to the stage2 section.
   Even with the improvements in this commit, I'm still seeing test
   failures in the widening behavior tests; more investigation is
   needed.
2021-10-04 23:30:04 -07:00
Robin Voetter
a1e02f33ad fmt 2021-10-04 11:25:29 +02:00
Robin Voetter
3dc47b8161 Apply new big int wrap/saturate to Value.zig 2021-10-04 11:25:29 +02:00
Robin Voetter
b352564b36 big ints: Some extra comments 2021-10-04 11:25:29 +02:00
Robin Voetter
bbd50248f2 big ints: saturate() function 2021-10-04 11:25:29 +02:00
Robin Voetter
fdf13fb819 big ints: Wrapping multiplication 2021-10-04 11:25:29 +02:00
Robin Voetter
41e9c1bac1 big ints: Allow llmulaccum to wrap 2021-10-04 11:25:29 +02:00
Robin Voetter
5907b3e383 big ints: Improve karatsuba multiplication 2021-10-04 11:25:29 +02:00
Robin Voetter
bb53f4f15a big ints: implement normal/wrapping/saturating subtraction in terms of addition 2021-10-04 11:25:29 +02:00
Robin Voetter
16991f920b big ints: saturating addition 2021-10-04 11:25:29 +02:00
Robin Voetter
f1b3a90ef6 big ints: setTwosCompIntLimit
This function can be used to initialize a big integer to either the upper
or lower limit of a 2s-complement integer. Note that the result is still
in sign-magnitude representation, though in order to convert it into twos
complement all one has to do is take the absolute value.
2021-10-04 11:25:29 +02:00
Robin Voetter
dc1f698545 big ints: unify add/sub with their wrapping variants 2021-10-04 11:25:29 +02:00
Robin Voetter
a36ef84deb big ints: Basic wrapping multiplication 2021-10-04 11:25:29 +02:00
Robin Voetter
69be6ba8ee Comptime wrapping addition/subtraction 2021-10-04 11:25:29 +02:00
Robin Voetter
fdb37743fa big ints: addWrap, subWrap + fix Managed.truncate allocation size 2021-10-04 11:25:29 +02:00
Robin Voetter
b58cf6dab6 big ints: 2s complement truncate 2021-10-04 11:25:29 +02:00
Robin Voetter
616b23c815 big ints: split lladd/llsub into carry variants
lladd is now implemented in terms of lladdcarry, which returns the carry limb.
Similarly, llsub is implemented using llsubcarry, which returns the borrow limb.
2021-10-04 11:25:29 +02:00
Robin Voetter
cd3dcc225b big ints: only write xor overflow if required 2021-09-23 06:28:09 +02:00
Robin Voetter
351e4f07ce big ints: 2s complement signed and + or fixes 2021-09-23 06:19:08 +02:00
Robin Voetter
f5c27dd11a big ints: 2s complement signed or 2021-09-23 04:08:27 +02:00