Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

std: big.int gcd #10932 miscompiled by self-hosted x86_64-linux backend #17998

Closed
kubkon opened this issue Nov 14, 2023 · 1 comment · Fixed by #18002
Closed

std: big.int gcd #10932 miscompiled by self-hosted x86_64-linux backend #17998

kubkon opened this issue Nov 14, 2023 · 1 comment · Fixed by #18002
Labels
arch-x86_64 64-bit x86 backend-self-hosted bug Observed behavior contradicts documented or intended behavior miscompilation The compiler reports success but produces semantically incorrect code.
Milestone

Comments

@kubkon
Copy link
Member

kubkon commented Nov 14, 2023

Zig Version

0.12.0-dev.1610+e88390743

Steps to Reproduce and Observed Behavior

Extracted from #17978

$ cat repro.zig
const std = @import("std");
const Managed = std.math.big.int.Managed;
const testing = std.testing;
const Limb = std.math.big.Limb;
const Const = std.math.big.int.Const;
const Mutable = std.math.big.int.Mutable;

test "repro" {
    var a = try Managed.init(testing.allocator);
    defer a.deinit();

    var b = try Managed.init(testing.allocator);
    defer b.deinit();

    var res = try Managed.init(testing.allocator);
    defer res.deinit();

    try a.setString(10, "3000000000000000000000000000000000000000000000000000000000000000000000001461501637330902918203684832716283019655932542975000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
    try b.setString(10, "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200001001500000000000000000100000000040000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000003000000000000000000000000000000000000000000000000000058715661000000000000000000000000000000000000023553252000000000180000000000000000000000000000000000000000000000000250000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001005000002000000000000000000000000000000000000000021000000001000000000000000000000000100000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000200000000000000000000004000000000000000000000000000000000000000000000301000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");

    try res.gcd(&a, &b);

    const ress = try res.toString(testing.allocator, 16, .lower);
    defer testing.allocator.free(ress);
    try testing.expect(std.mem.eql(u8, ress, "1a974a5c9734476ff5a3604bcc678a756beacfc21b4427d1f2c1f56f5d4e411a162c56136e20000000000000000000000000000000"));
}
$ zig test repro.zig -fno-llvm -fno-lld
Test [1/1] test.repro...

Never terminates.

If you swap in std.heap.page_allocator for testing.allocator, the test runs fine. If you insert a dummy print statement in gcdLehmer it also terminates fine:

diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig
index 346da746d..dca26def3 100644
--- a/lib/std/math/big/int.zig
+++ b/lib/std/math/big/int.zig
@@ -1449,6 +1449,7 @@ pub const Mutable = struct {
         while (y.len() > 1 and !y.eqlZero()) {
             assert(x.isPositive() and y.isPositive());
             assert(x.len() >= y.len());
+            std.io.getStdErr().writer().writeByte(0) catch {};
 
             var xh: SignedDoubleLimb = x.limbs[x.len() - 1];
             var yh: SignedDoubleLimb = if (x.len() > y.len()) 0 else y.limbs[x.len() - 1];

Expected Behavior

The test should terminate and pass.

@kubkon kubkon added bug Observed behavior contradicts documented or intended behavior arch-x86_64 64-bit x86 backend-self-hosted os-linux labels Nov 14, 2023
@kubkon
Copy link
Member Author

kubkon commented Nov 14, 2023

I should add that I couldn't work out exactly if this is a codegen bug or a linker bug yet.

@Vexu Vexu added this to the 0.13.0 milestone Nov 14, 2023
@jacobly0 jacobly0 added miscompilation The compiler reports success but produces semantically incorrect code. and removed os-linux labels Nov 14, 2023
@jacobly0 jacobly0 modified the milestones: 0.13.0, 0.12.0 Nov 14, 2023
jacobly0 added a commit to jacobly0/zig that referenced this issue Nov 14, 2023
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
arch-x86_64 64-bit x86 backend-self-hosted bug Observed behavior contradicts documented or intended behavior miscompilation The compiler reports success but produces semantically incorrect code.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants