Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

x86_64 backend: @intCast in airBitCast failing on !PathSpace return type #15904

Closed
squeek502 opened this issue May 30, 2023 · 0 comments · Fixed by #15905
Closed

x86_64 backend: @intCast in airBitCast failing on !PathSpace return type #15904

squeek502 opened this issue May 30, 2023 · 0 comments · Fixed by #15905
Labels
arch-x86_64 64-bit x86 backend-self-hosted bug Observed behavior contradicts documented or intended behavior
Milestone

Comments

@squeek502
Copy link
Collaborator

squeek502 commented May 30, 2023

Zig Version

0.11.0-dev.3324+706bdf651

Steps to Reproduce and Observed Behavior

This is a minimal reproduction of the crashes caused by #15768 (see #15768 (comment))

// test.zig
const std = @import("std");
const PathSpace = std.os.windows.PathSpace;

fn foo() !PathSpace {
    return bar();
}

fn bar() !PathSpace {
    var path_space: PathSpace = undefined;
    return path_space;
}

pub fn main() !void {
    _ = try foo();
}
zig build-exe test.zig -fno-LLVM

Output (with a debug print to print the failing abiSize and bitSize):

> zig build-exe empty.zig -fno-LLVM
abiSize: 0x10010 bitSize: 0x80080
thread 8140 panic: integer cast truncated bits
Analyzing empty.zig: empty.zig:main
      %60 = dbg_block_begin()
      %61 = dbg_stmt(2, 9)
      %62 = decl_val("foo") token_offset:14:13 to :14:16
      %63 = dbg_stmt(2, 16)
      %64 = call(.auto, %62, []) node_offset:14:13 to :14:18
    > %65 = try(%64, {
        %66 = err_union_code(%64) node_offset:14:9 to :14:18
        %67 = dbg_stmt(2, 9)
        %68 = ret_node(%66) node_offset:14:9 to :14:18
      }) node_offset:14:9 to :14:18
      %69 = ensure_result_non_error(%65) node_offset:14:9 to :14:18
      %70 = dbg_block_end()
      %71 = restore_err_ret_index(%59, @Zir.Inst.Ref.none)
      %72 = break(%59, @Zir.Inst.Ref.void_value)
    For full context, use the command
      zig ast-check -t empty.zig

  in empty.zig: empty.zig:main
    > %59 = block({%60..%72}) node_offset:13:21 to :13:22
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:callMain
    > %3049 = is_non_err(%3048)
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:callMain
    > %3051 = block({%3045..%3050})
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:callMain
    > %3042 = block({%3043..%3192})
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:callMain
    > %2947 = switch_block(%2944,
        else => {%3195..%3201},
        %2949 => {%2950..%2962},
        %2964 => {%2965..%2983},
        %2986 => {%2984..%3038},
        %3040 => {%3041..%3194})
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:callMain
    > %2929 = block({%2930..%3205})
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:initEventLoopAndCallMain
    > %2650 = builtin_call(%2648, %2649, @Zir.Inst.Ref.empty_struct)
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:initEventLoopAndCallMain
    > %2497 = block({%2498..%2658})
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:WinStartup
    > %1586 = call(.auto, %1584, [])
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:WinStartup
    > %1583 = field_call(nodiscard .auto, %1580, ExitProcess, [
        {%1584..%1587},
      ])
  in C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig: start.zig:WinStartup
    > %1529 = block({%1530..%1590})

C:\Users\Ryan\Programming\Zig\zig\src\arch\x86_64\CodeGen.zig:10179:26: 0x7ff64d46bd1a in airBitCast (zig.exe.obj)
        const abi_size = @intCast(u16, dst_ty.abiSize(self.target.*));
                         ^
C:\Users\Ryan\Programming\Zig\zig\src\arch\x86_64\CodeGen.zig:1813:52: 0x7ff64d108304 in genBody (zig.exe.obj)
            .bitcast         => try self.airBitCast(inst),
                                                   ^
C:\Users\Ryan\Programming\Zig\zig\src\arch\x86_64\CodeGen.zig:1600:25: 0x7ff64cd83b3c in gen (zig.exe.obj)
        try self.genBody(self.air.getMainBody());
                        ^
C:\Users\Ryan\Programming\Zig\zig\src\arch\x86_64\CodeGen.zig:729:17: 0x7ff64c9802a7 in generate (zig.exe.obj)
    function.gen() catch |err| switch (err) {
                ^
C:\Users\Ryan\Programming\Zig\zig\src\codegen.zig:85:70: 0x7ff64c48cc3d in generateFunction (zig.exe.obj)
        .x86_64 => return @import("arch/x86_64/CodeGen.zig").generate(bin_file, src_loc, func, air, liveness, code, debug_output),
                                                                     ^
C:\Users\Ryan\Programming\Zig\zig\src\link\Coff.zig:1057:45: 0x7ff64c4890a6 in updateFunc (zig.exe.obj)
    const res = try codegen.generateFunction(
                                            ^
C:\Users\Ryan\Programming\Zig\zig\src\link.zig:578:77: 0x7ff64c1d82e3 in updateFunc (zig.exe.obj)
            .coff  => return @fieldParentPtr(Coff,  "base", base).updateFunc(module, func, air, liveness),
                                                                            ^
C:\Users\Ryan\Programming\Zig\zig\src\Module.zig:4406:37: 0x7ff64bfc96e2 in ensureFuncBodyAnalyzed (zig.exe.obj)
            comp.bin_file.updateFunc(mod, func, air, liveness) catch |err| switch (err) {
                                    ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:28955:36: 0x7ff64caf0c69 in ensureFuncBodyAnalyzed (zig.exe.obj)
    sema.mod.ensureFuncBodyAnalyzed(func) catch |err| {
                                   ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:31650:40: 0x7ff64c5cb5bf in resolveInferredErrorSet (zig.exe.obj)
        try sema.ensureFuncBodyAnalyzed(ies.func);
                                       ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:29247:49: 0x7ff64c599131 in analyzeIsNonErrComptimeOnly (zig.exe.obj)
                try sema.resolveInferredErrorSet(block, src, ies);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:17083:60: 0x7ff64c598117 in zirTry (zig.exe.obj)
    const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
                                                           ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1616:67: 0x7ff64c2019b2 in analyzeBodyInner (zig.exe.obj)
                if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
                                                                  ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5483:33: 0x7ff64c59c536 in zirBlock (zig.exe.obj)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1461:49: 0x7ff64c203aed in analyzeBodyInner (zig.exe.obj)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:804:30: 0x7ff64c47517e in analyzeBody (zig.exe.obj)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Module.zig:5709:21: 0x7ff64c1d5ed4 in analyzeFnBody (zig.exe.obj)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
C:\Users\Ryan\Programming\Zig\zig\src\Module.zig:4338:40: 0x7ff64bfc8db5 in ensureFuncBodyAnalyzed (zig.exe.obj)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:28955:36: 0x7ff64caf0c69 in ensureFuncBodyAnalyzed (zig.exe.obj)
    sema.mod.ensureFuncBodyAnalyzed(func) catch |err| {
                                   ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:31650:40: 0x7ff64c5cb5bf in resolveInferredErrorSet (zig.exe.obj)
        try sema.ensureFuncBodyAnalyzed(ies.func);
                                       ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:29247:49: 0x7ff64c599131 in analyzeIsNonErrComptimeOnly (zig.exe.obj)
                try sema.resolveInferredErrorSet(block, src, ies);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:29274:56: 0x7ff64ca3c8ea in analyzeIsNonErr (zig.exe.obj)
    const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                       ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:16970:32: 0x7ff64c4e066d in zirIsNonErr (zig.exe.obj)
    return sema.analyzeIsNonErr(block, src, operand);
                               ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:966:66: 0x7ff64c1f1491 in analyzeBodyInner (zig.exe.obj)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5483:33: 0x7ff64c59c536 in zirBlock (zig.exe.obj)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1461:49: 0x7ff64c203aed in analyzeBodyInner (zig.exe.obj)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5483:33: 0x7ff64c59c536 in zirBlock (zig.exe.obj)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1461:49: 0x7ff64c203aed in analyzeBodyInner (zig.exe.obj)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:11001:49: 0x7ff64c4f1054 in zirSwitchBlock (zig.exe.obj)
                    return sema.resolveBlockBody(block, src, &child_block, body, inst, merges);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:989:69: 0x7ff64c1f29f1 in analyzeBodyInner (zig.exe.obj)
            .switch_block                 => try sema.zirSwitchBlock(block, inst),
                                                                    ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5483:33: 0x7ff64c59c536 in zirBlock (zig.exe.obj)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1461:49: 0x7ff64c203aed in analyzeBodyInner (zig.exe.obj)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:804:30: 0x7ff64c47517e in analyzeBody (zig.exe.obj)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:6963:33: 0x7ff64ca23512 in analyzeCall (zig.exe.obj)
                sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:21716:28: 0x7ff64c5310cd in zirBuiltinCall (zig.exe.obj)
    return sema.analyzeCall(block, func, func_ty, func_src, call_src, modifier, ensure_result_used, resolved_args, null, null);
                           ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1045:69: 0x7ff64c1f5e41 in analyzeBodyInner (zig.exe.obj)
            .builtin_call                 => try sema.zirBuiltinCall(block, inst),
                                                                    ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5483:33: 0x7ff64c59c536 in zirBlock (zig.exe.obj)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1461:49: 0x7ff64c203aed in analyzeBodyInner (zig.exe.obj)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:804:30: 0x7ff64c47517e in analyzeBody (zig.exe.obj)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:6963:33: 0x7ff64ca23512 in analyzeCall (zig.exe.obj)
                sema.analyzeBody(&child_block, fn_info.body) catch |err| switch (err) {
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:6403:32: 0x7ff64c4cf641 in zirCall__anon_132153 (zig.exe.obj)
        return sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, resolved_args, bound_arg_src, call_dbg_node);
                               ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:923:62: 0x7ff64c1eec44 in analyzeBodyInner (zig.exe.obj)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:821:45: 0x7ff64bfea330 in analyzeBodyBreak (zig.exe.obj)
    const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                                            ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:770:50: 0x7ff64ca17c3c in resolveBody (zig.exe.obj)
    const break_data = (try sema.analyzeBodyBreak(block, body)) orelse
                                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:6349:46: 0x7ff64c4d0ff6 in zirCall__anon_132155 (zig.exe.obj)
        const resolved = try sema.resolveBody(block, args_body[arg_start..arg_end], inst);
                                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:924:62: 0x7ff64c1eed30 in analyzeBodyInner (zig.exe.obj)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5500:34: 0x7ff64ca58b74 in resolveBlockBody (zig.exe.obj)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:5483:33: 0x7ff64c59c536 in zirBlock (zig.exe.obj)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:1461:49: 0x7ff64c203aed in analyzeBodyInner (zig.exe.obj)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
C:\Users\Ryan\Programming\Zig\zig\src\Sema.zig:804:30: 0x7ff64c47517e in analyzeBody (zig.exe.obj)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Module.zig:5709:21: 0x7ff64c1d5ed4 in analyzeFnBody (zig.exe.obj)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
C:\Users\Ryan\Programming\Zig\zig\src\Module.zig:4338:40: 0x7ff64bfc8db5 in ensureFuncBodyAnalyzed (zig.exe.obj)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
C:\Users\Ryan\Programming\Zig\zig\src\Compilation.zig:3128:42: 0x7ff64bfc6d4d in processOneJob (zig.exe.obj)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
C:\Users\Ryan\Programming\Zig\zig\src\Compilation.zig:3065:30: 0x7ff64be93175 in performAllTheWork (zig.exe.obj)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
C:\Users\Ryan\Programming\Zig\zig\src\Compilation.zig:2021:31: 0x7ff64be8f5da in update (zig.exe.obj)
    try comp.performAllTheWork(main_progress_node);
                              ^
C:\Users\Ryan\Programming\Zig\zig\src\main.zig:3866:24: 0x7ff64bebd344 in updateModule (zig.exe.obj)
        try comp.update(main_progress_node);
                       ^
C:\Users\Ryan\Programming\Zig\zig\src\main.zig:3301:17: 0x7ff64bd304b4 in buildOutputType (zig.exe.obj)
    updateModule(comp) catch |err| switch (err) {
                ^
C:\Users\Ryan\Programming\Zig\zig\src\main.zig:269:31: 0x7ff64bd02e71 in mainArgs (zig.exe.obj)
        return buildOutputType(gpa, arena, args, .{ .build = .Exe });
                              ^
C:\Users\Ryan\Programming\Zig\zig\src\main.zig:213:20: 0x7ff64bd02a1e in main (zig.exe.obj)
    return mainArgs(gpa, arena, args);
                   ^
C:\Users\Ryan\Programming\Zig\zig\lib\std\start.zig:508:80: 0x7ff64bd04951 in main (zig.exe.obj)
    return @call(.always_inline, callMainWithArgs, .{ @intCast(usize, c_argc), @ptrCast([*][*:0]u8, c_argv), envp });
                                                                               ^
???:?:?: 0x7ff64dae4034 in ??? (zig.exe)
???:?:?: 0x7ff64dae408b in ??? (zig.exe)
???:?:?: 0x7fff3d197613 in ??? (KERNEL32.DLL)
???:?:?: 0x7fff3d9e26a0 in ??? (ntdll.dll)

Notes:

  • Does not reproduce if foo returns a PathSpace directly (i.e. it needs the call to bar to reproduce the problem)
  • Does not reproduce if foo does not return an error union
  • The airBitCast function is seemingly not called at all for the !PathSpace return type in instances where the problem does not reproduce, but I could totally be wrong about that

Expected Behavior

No compiler crash

@squeek502 squeek502 added the bug Observed behavior contradicts documented or intended behavior label May 30, 2023
@andrewrk andrewrk added this to the 0.11.0 milestone May 30, 2023
jacobly0 added a commit to jacobly0/zig that referenced this issue May 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-x86_64 64-bit x86 backend-self-hosted bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants